Adding foreign keys can sometimes be tricky. You might get an error message or see that it doesn't work as expected.
There are 3 common mistakes that we see developers make when adding foreign keys to their databases:
- Forgetting to add Constraints
- Adding new Foreign Keys Without Proper Default Data
- Allowing to Delete Parent Records when Child Record Exists
Let's see those mistakes and how to fix them!
Mistake 1: Forgetting to add Constraints
Database constraints are a valuable feature we should not ignore. They help us protect from missing related records in our database.
Let's build a basic example here:
Migration
// Create Categories tableSchema::create('categories', function (Blueprint $table) { $table->id(); $table->string('category')->nullable(); $table->timestamps();}); // Create a child Questions table with a relationship to the parent Categories tableSchema::create('questions', function (Blueprint $table) { $table->id(); $table->foreignId('category_id'); $table->longText('question')->nullable(); $table->longText('answer')->nullable(); $table->timestamps();});
You might think that we are good to go here. However, we are not. It allows us to create new Questions with a category that doesn't exist:
$question = Question::create([ 'category_id' => 155, 'question' => 'How to use Laravel?', 'answer' => 'You can use Laravel by following the documentation',]);
And this will work perfectly fine. Why? Because we don't tell our database to check for the category id.

We have 0 categories in our database, but we can still create a new Question with category id 155. It is not good. Let's fix it!
Migration
// ... // Create a child Questions table with a relationship to the parent Categories tableSchema::create('questions', function (Blueprint $table) { $table->id(); $table->foreignId('category_id')->constrained(); $table->longText('question')->nullable(); $table->longText('answer')->nullable(); $table->timestamps();});
When we try to run the same code of Question::create(), we get an error...
Premium Members Only
This advanced tutorial is available exclusively to Laravel Daily Premium members.
Already a member? Login here
Premium membership includes:
Hey there! Great article! Thanks for sharing it. But...is it me, or am I seeing the same example in Mistake 1, when it is suppose to show the correct code? I think it is the same sample code that in the first part. Thanks!
Of course! Well spotted, lost it in the editing/reviewing process, fixed now, the mistake was NOT using
constrained().Useful article!
Labai praverte darant baigiamaji codeacademi darba. Visi trys atvejai buvo kur buvo kile klausimu.
Great article!
Hi! Great article. But I saw a mistake in the last example. We load the count in the controller but in the template use queries to count. I think we need to use count property
@if($category->questions_count === 0)Thank you for spotting this! Updating the example