Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel foreign key onDelete('cascade') not working

I have a many-to-many relationship between User & Role, with a role_user table. My migrations are setup as so (simplified):

users table:

public function up()
{
    Schema::create('users', function(Blueprint $table)
    {
        $table->increments('id');
        $table->string('email')->unique();
    });
}

roles table:

public function up()
{
    Schema::create('roles', function(Blueprint $table)
    {
        $table->increments('id');
        $table->string('name');
    });
}

role_user table:

public function up()
{
    Schema::create('role_user', function(Blueprint $table)
    {
        $table->increments('id');
        $table->integer('user_id')->unsigned();
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        $table->integer('role_id')->unsigned();
        $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
    });
}

So as per the docs, I set my foreign keys to unsigned.

Now, I add a couple of users, and attach some roles - everything works fine. However, when I delete a user (User::destroy(2)) the rows for that user in the role_user table do not get deleted, which is causing redundant rows.

What am I doing wrong?

  • MySQL + InnoDB

EDIT: Grabbing the model and applying ->delete(); also has the same effect.

like image 845
Alias Avatar asked Jul 22 '14 20:07

Alias


People also ask

What is onDelete (' cascade ') in laravel?

The onDelete('cascade') means that when the row is deleted, it will delete all it's references and attached data too. For example if you have a User which has a Post and you set onDelete('cascade') on the user, then when the user deletes his account, all posts will be deleted as well.

How to use CASCADE ON DELETE?

Use the ON DELETE CASCADE option to specify whether you want rows deleted in a child table when corresponding rows are deleted in the parent table. If you do not specify cascading deletes, the default behavior of the database server prevents you from deleting data in a table if other tables reference it.

What is CASCADE update and CASCADE DELETE?

ON UPDATE CASCADE ON DELETE CASCADE means that if you UPDATE OR DELETE the parent, the change is cascaded to the child. This is the equivalent of AND ing the outcomes of first two statements.

How to use ON DELETE SET NULL in MySQL?

SET NULL : Delete or update the row from the parent table and set the foreign key column or columns in the child table to NULL . Both ON DELETE SET NULL and ON UPDATE SET NULL clauses are supported. If you specify a SET NULL action, make sure that you have not declared the columns in the child table as NOT NULL .

How to use cascade operation in Laravel?

In Laravel, we can apply the CASCADE operation like this: In simple words, if for an example you delete a user row in your users table, all the related posts records that are referencing that user_id will also be deleted, if we use the onDelete () method with cascade argument.

How to enable foreign key constraints in Laravel migrations?

In SQLite foreign key constraints are disabled by default. You should enable them, before setting foreign key constraints in the migrations. Luckily, in the database config file config/database.php, Laravel has it set to be enabled by default, if the env constant DB_FOREIGN_KEYS is not set.

Is it possible to Cascade ondelete with softdeletes?

For someone that's here and using SoftDeletes on their models; onDelete ('cascade') functionality is lost when using SoftDeletes. Options you could use in such a case are:

Is there a delete cascade effect in child table?

the entry from parent table is deleted but their is no delete cascade effect in child table (BOOK table). Can someone help me what I am doing wrong. Show activity on this post. Aftee searching the Ideone FAQ, it seems that it uses Sqlite3 for the SQL language.


2 Answers

Check the MySQL config. my.ini may still have default-storage-engine=MYISAM. Set to default-storage-engine=InnoDB and you should avoid the trouble of adding this fix to each migration.

like image 70
STWilson Avatar answered Sep 25 '22 08:09

STWilson


It is established by Jake's answer that you have set default engine to InnoDB

$table->engine = 'InnoDB';

Instead of doing it in each migration file, You can do so in config/database.php

'mysql' => [
        'driver' => 'mysql',
        'host' => env('DB_HOST', '127.0.0.1'),
        'port' => env('DB_PORT', '3306'),
        'database' => env('DB_DATABASE', 'forge'),
        'username' => env('DB_USERNAME', 'forge'),
        'password' => env('DB_PASSWORD', ''),
        'unix_socket' => env('DB_SOCKET', ''),
        'charset' => 'utf8mb4',
        'collation' => 'utf8mb4_unicode_ci',
        'prefix' => '',
        'strict' => false,
        'engine' => 'InnoDB',
    ],
like image 25
Shreyansh Panchal Avatar answered Sep 24 '22 08:09

Shreyansh Panchal