1
votes

I am trying to learn one-to-one relations. I am using Laravel 5.5.13.

My simple app is this:

I create a App\Message. I optionally can associate a App\Task with it.

My goal:

  • Once a App\Task is associated, if the task is deleted, it should cascade delete the App\Message row.
  • And the reverse, if the App\Message is deleted, it should cascade and delete the App\Task row.

However I am having an error on migrate because the tasks_table is created AFTER the messages_table.

Here is my migration:

2017_10_15_021803_create_messages_table.php:

public function up()
{
    Schema::create('messages', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('task_id')->unsigned()->nullable();
        $table->text('body');
        $table->timestamps();

        $table->foreign('task_id')->references('id')->on('tasks')->onDelete('cascade'); //// IF I COMMENT THIS OUT THE MIGRATION WORKS, BUT I NEED THIS IN

    });
}

And for App\Task 2017_10_15_023343_create_tasks_table.php:

public function up()
{
    Schema::create('tasks', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('message_id')->unsigned();
        $table->timestamps();

        $table->foreign('message_id')->references('id')->on('messages')->onDelete('cascade');
    });
}

If I comment out the $table->foreign('task_id')->references('id')->on('tasks')->onDelete('cascade'); then the migration works, BUT i need the deletion of the message when the task is deleted, and without this line that won't happen.

The error I get after running php artisan migrate is:

[Illuminate\Database\QueryException] SQLSTATE[HY000]: General error: 1005 Can't create table petfolk.#sql-42e8_16f (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table messages add constraint messages_task_id_foreign foreign key (task_id) references tasks (id) on delete set null)

[PDOException] SQLSTATE[HY000]: General error: 1005 Can't create table petfolk.#sql-42e8_16f (errno: 150 "Foreign key constraint is incorrectly formed")

2
What is the error that you get?Omar Tarek
Thanks @OmarTarek for the fast reply and reminder! I added the error info. Thanks!Blagoh

2 Answers

1
votes

Just create third migration and move foreign key adding logic in the migration:

Schema::table('messages', function (Blueprint $table) {
    $table->foreign('task_id')->references('id')->on('tasks')->onDelete('cascade');
}

It will work when both tables will be created.

1
votes

A one-to-one relationship links one row in a database table to one (and only one) row in another table.

onDelete('cascade') is used when there is an intermediate, also known as a pivot, table between two tables in a many-to-many relationship. You do not need this for a one-to-one relationship because the link to the messages table only exists in the row of the tasks table (and that is being deleted).

Try this for the tasks table migration:

public function up()
{
    Schema::create('tasks', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('message_id')->unsigned()->nullable();
        $table->foreign('message_id')->references('id')->on('messages');
        $table->timestamps();

    });
}