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...