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.