Integrity constraint violation: 1452 laravel

21,174

Your final sql query is insert into occasions (updated_at, created_at) values (2014-06-30 18:42:11, 2014-06-30 18:42:11). You should see that only updated_at and created_at is being inserted.

This happens because Laravel protects your code against against Mass Assignment by default:

If user input is blindly passed into a model, the user is free to modify any and all of the model's attributes. For this reason, all Eloquent models protect against mass-assignment by default.

You'll need to make your columns fillable by adding an array of $fillable columns in your model:

class Occasion extends Eloquent
{
    protected $fillable = array(
        'created_by_user_id',
        'updated_by_user_id',
        // The rest of the column names that you want it to be mass-assignable.
    );
}

Or do the opposite, guard any columns that you don't want them to be mass-assignable:

class Occasion extends Eloquent
{
    protected $guarded = array(
        // Any columns you don't want to be mass-assignable.
        // Or just empty array if all is mass-assignable.
    );
}

Note that you are assigning Input::get() into the model directly. Here is a caution from Mass Assignment section:

Note: When using guarded, you should still never pass Input::get() or any raw array of user controlled input into a save or update method, as any column that is not guarded may be updated.

Share:
21,174
user3527894
Author by

user3527894

Updated on July 01, 2020

Comments

  • user3527894
    user3527894 almost 4 years

    I have two tables in laravel created with the following migrations:

    User migration:

    public function up()
    {
        Schema::create('users', function($table){
            $table->increments('id')->unsigned();
            $table->string('email')->unique();
            $table->string('password', 64);
            $table->string('first_name', 32);
            $table->string('last_name', 32);
            $table->string('remember_token', 100)->nullable();
        });
    }
    

    Occasion migration:

    public function up()
    {
        Schema::create('occasions', function($table){
            $table->increments('id')->unsigned();
            $table->integer('created_by_user_id')->unsigned();
            $table->foreign('created_by_user_id')->references('id')->on('users');
            $table->integer('updated_by_user_id')->unsigned();
            $table->foreign('updated_by_user_id')->references('id')->on('users');
            $table->timestamps();
            $table->string('title')->unique();
            $table->string('slug')->unique();
            $table->integer('category')->unsigned();
            $table->foreign('category')->references('id')->on('occasion_categories');
            $table->string('brand', 32);
            $table->string('model', 32)->nullable();
            $table->string('type', 32)->nullable();
            $table->string('body', 32)->nullable();
            $table->string('color', 32);
            $table->integer('fuel')->unsigned()->nullable();
            $table->foreign('fuel')->references('id')->on('occasion_fuels');
            $table->integer('transmission')->unsigned()->nullable();
            $table->foreign('transmission')->references('id')->on('occasion_transmissions');
            $table->decimal('usage', 6, 2)->nullable();
            $table->integer('engine_capacity')->unsigned()->nullable();
            $table->integer('building_year')->unsigned()->nullable();
            $table->string('sign', 8)->nullable();
            $table->date('mot')->nullable();
            $table->integer('kilometers')->nullable();
            $table->decimal('price', 8, 2);
            $table->decimal('action_price', 8, 2)->nullable();
            $table->text('description')->nullable();
        });
    }
    

    Now when I try to create a Occasion with the following code:

    Occasion::create(array(
        'created_by_user_id'=>Auth::id(),
        'updated_by_user_id'=>Auth::id(),
        'title'=>Input::get('title'),
        'slug'=>Str::slug(Input::get('title')),
        'category'=>Input::get('category'),
        'brand'=>Input::get('brand'),
        'model'=>Input::get('model'),
        'type'=>Input::get('type'),
        'body'=>Input::get('body'),
        'color'=>Input::get('color'),
        'fuel'=>Input::get('fuel'),
        'transmission'=>Input::get('transmission'),
        'usage'=>Input::get('usage'),
        'engine_capacity'=>Input::get('engine-capacity'),
        'building_year'=>Input::get('building-year'),
        'sign'=>Input::get('sign'),
        'mot'=>Input::get('mot'),
        'kilometers'=>Input::get('kilometers'),
        'price'=>Input::get('price'),
        'action_price'=>Input::get('action-price'),
        'description'=>Input::get('description')
    ));
    

    I get the following error:

    SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (henw.occasions, CONSTRAINT occasions_created_by_user_id_foreign FOREIGN KEY (created_by_user_id) REFERENCES users (id)) (SQL: insert into occasions (updated_at, created_at) values (2014-06-30 18:42:11, 2014-06-30 18:42:11))

    I searched on Google but most of the people say I get this error because the foreign key does not exists, but that isn't true, because when i try to add the same values in PhpMyAdmin it does work and the user id which i am inserting is 1 and it does exist.

  • user3527894
    user3527894 almost 10 years
    Thanks! I have an array fillable filled with all the names of attributs and now it works! But is that safe to do it like that?
  • Unnawut
    Unnawut almost 10 years
    AFAIK, you will be protected against SQL injection. But you will still need to do your own input validation to make sure the data is valid laravel.com/docs/validation
  • Ingwie Phoenix
    Ingwie Phoenix over 8 years
    I have the same error message, except it reads differently for me since i have different tables. How would I be able to read off the error string which fields are being guarded on purpose? I kinda don't know where the problem really lies. o.o...