Set Foreign Key to 'NULL' When delete Relationship in Laravel

Viewed 1995

My question is related to Laravel, I have product model and categories. They have a relationship with category_id as a foreign key to product table, my question is, I need when I delete a category, this category_id related field be NULL, I mean, there's a Laravel way to do it? Without be in migration.

This is my Category Model:

public function products()
{
    return $this->hasMany('App\Models\Product');
}

This is my Product model:

    public function category()
{
    return $this->belongsTo('App\Models\Category')->withDefault(function ($data) {
        foreach($data->getFillable() as $dt){
            $data[$dt] = __('Deleted');
        }
    });
}
2 Answers

Edit:

I mean its probably possible but I wouldn't recommend doing something that way. You could theoretically do a database query that gets all products that have the category_id of the the category you just deleted, then update them to null as long as your column accounts for null values. You would simply call this (or some variation of this) whenever you're deleting a category. This may have major performance impacts based on the size of the table you're doing this on.

ie. (using model):

Products::where('category_id', '=', $id_i_deleted)->update(['category_id' => null]);

or (using DB):

DB::table('products')->where('category_id', '=', $id_i_deleted)->update(['category_id' => null]);

But I would highly recommend just biting the bullet and altering your table structure. It'll save you infinite headaches in the long run.

Original:

Yes, it is definitely possible! Here is how you should set up your foreign key if you want it to allow for a null value:

Schema::table('products', function(Blueprint $table) {
    $table->integer('category_id')->unsigned()->nullable();
    $table->foreign('category_id')->references('id')->on('categories')->onDelete('set null');
});

Shorter way using a helper:

Schema::table('products', function(Blueprint $table) {
    $table->foreignId('category_id')->nullable()->constrained()->on('categories')->nullOnDelete();
});
Related