0

I have tried add foreign key constraint using migrations. The migration completes without any error. However, when the database is checked, the foreign key constraint is not added to the table. Other things specified in the migrations work fine except of FK constraint.

My pivot table with FKs:

Schema::create('book_author', function (Blueprint $table) {

            $table->integer('book_id')->unsigned();
            $table->integer('author_id')->unsigned();

            $table->foreign('book_id')->references('id')->on('book')->onDelete('restrict')->onUpdate('cascade');
            $table->foreign('author_id')->references('id')->on('author')->onDelete('restrict')->onUpdate('cascade');
            $table->primary(['book_id','author_id']);

        });
        Schema::enableForeignKeyConstraints();

Author table:

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

Book table:

 Schema::create('book', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
        });

Is there anything I'm missing here?

8
  • Which database? How are you checking to make sure the foreign key is there? Commented Jan 20, 2017 at 17:21
  • By adding a field with bogus 'id' values for both columns. Commented Jan 20, 2017 at 17:54
  • Is your table engine InnoDB or MyISAM? Commented Jan 20, 2017 at 18:00
  • Have you tried making the changes I suggested in my answer? If so is the problem still there? Commented Jan 20, 2017 at 18:04
  • Yes. Same result. No difference. BTW I didn't down vote your answer. Commented Jan 20, 2017 at 18:24

2 Answers 2

1

MyISAM doesn't support foreign key: http://dev.mysql.com/doc/refman/5.7/en/myisam-storage-engine.html

Run the following command to make sure which engine your table has:

SHOW TABLE STATUS WHERE Name = 'book_author'

If it shows MyISAM, you have two option:

  1. don't use FK at all
  2. Replace your engine

I would go with option 2, because you are creating a new table and there is no risk to lose data here.

You can force in your migrations with:

$table->engine = 'InnoDB';

Alternatively, you can run this command manually:

ALTER TABLE book_author ENGINE=INNODB
Sign up to request clarification or add additional context in comments.

Comments

0

Change your book_author migration to:

Schema::create('book_author', function (Blueprint $table) {
    $table->integer('book_id')->unsigned()->index();
    $table->integer('author_id')->unsigned()->index();

    $table->foreign('book_id')->references('id')->on('book')->onDelete('cascade')->onUpdate('cascade');
    $table->foreign('author_id')->references('id')->on('author')->onDelete('cascade')->onUpdate('cascade');
});

This should work.


On the other note you're breaking a few Laravel conventions with your table names:

  1. Name your tables in plural form (authors & books)
  2. The pivot table (book_author) should be called (author_book) - alphabetical priority.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.