Search code examples
phpmysqllaravelforeign-keyslaravel-9

SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row in Laravel9


I have an integrity constraint violation when I run the php artisan db:seed command in Laravel 9.

Error

PDOException::("SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (hunger-db.restaurants, CONSTRAINT restaurants_user_id_foreign FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE)")

setup_users_table

public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('email')->unique();
        $table->timestamp('email_verified_at')->nullable();
        $table->string('password');
        $table->string('phone');
        $table->tinyInteger('role_as')->default('0');
        $table->tinyInteger('gender')->default('0');
        $table->string('date_of_birth')->default('1999/9/9');
        $table->rememberToken();

        $table->timestamps();
    });
}

setum_restaurants_table

public function up()
{
    Schema::create('restaurants', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('img_src');
        $table->string('description');
        $table->string('minimum_order_amount');
        $table->string('working_hours_open');
        $table->string('working_hours_close');
        $table->string('delivery_time');
        $table->string('delivery_fee');
        $table->boolean('status')->default('0');
        $table->unsignedBigInteger('user_id')->default('1');
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        $table->timestamps();
    });
}

User Model

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    protected $fillable = [
        'name',
        'email',
        'password',
        'phone',
    ];

    public function orders()
    {
        return $this->hasMany(Order::class);
    }

    public function restaurants()
    {
        return $this->belongsTo(Restaurant::class);
    }
}

Restaurant Model

class Restaurant extends Model
{
    use HasFactory;

    protected $fillable = [
        'name',
        'img_src',
        'description',
    ];
    public function users()
    {
        return $this->belongsTo(User::class);
    }
}

Solution

  • I see some things to change here

    setup_restaurants_table

    I don't see with good eyes user_id with default 1, maybe is better to define the value when restaurant is created or manually assign it to user 1.

    Schema::create('restaurants', function (Blueprint $table) {
            $table->id();
            ...
            $table->foreignId('user_id')->constrained()->onDelete('CASCADE');
    });
    

    After DB changes run php artisan migrate:fresh

    User.php

    Should change relation to hasMany Restaurants

    public function restaurants()
    {
        return $this->hasMany(Restaurant::class);
    }
    
    

    Seeding

    Also ensure your DB seeding is correct, I mean creating user first and then restaurant, set user_id with an existing value.

    Maybe creating a restaurant like this:

    $user = User::factory()
                ->hasRestaurants(3)
                ->create();
    

    If any factory change run php artisan db:seed

    Can also see Factory Retationship Docs