We know that there are some well-known relationships, such as one-to-one, one-to-many, and many-to-many but, have you ever heard about the recursive one-to-one or recursive one-to-many or even recursive many-to-many relationships?
The recursive relationship is a relation BETWEEN the table and itself.
Let's imagine we work on a Social project and want to implement the Comments section. The database implementation may differ from one to another, where someone will say that I will make `comments` and `comment_replies` tables, and these tables have almost the same structure, but the `comment_replies` has an additional foreign key to refer to its parent comment
I will not ever recommend this implementation because he will implement the recursive one-to-many relationship after creating the previous structure.
So let's take the closest route by using the recursive one-to-many relationship directly via creating the `comments` table only with the foreign key to point to its parent comment:
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->text('body');
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->foreignId('post_id')->constrained()->cascadeOnDelete();
$table->foreignId('comment_id')->nullable()->constrained();
$table->timestamps();
});
}
Now, we have an amazing schema, but when someone comes to read the migration file and finds the `comment_id` column, he will be confused. So, let's make it more understandable:
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->text('body');
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->foreignId('post_id')->constrained()->cascadeOnDelete();
$table->foreignId('parent_id')->nullable()->constrained('comments');
$table->timestamps();
});
}
We renamed the `comment_id` to `parent_id` because we do not have the `parents` table so, we passed the correct table name into the `constrained` method, and every parent comment will have no `parent_id` value but, will have a valueโโโโโโ for its replies.