Home » Php » How to implement a self referencing (parent_id) model in Eloquent Orm

How to implement a self referencing (parent_id) model in Eloquent Orm

Posted by: admin October 29, 2017 Leave a comment

Questions:

I have a User table and need to allow for users to have a parent user.

the table would have the fields:

  • id
  • parent_id
  • email
  • password

How would I define this self referencing relationship in Eloquent ORM?

Answers:

I had some success like this, using your exact DB table.

User Model:

class User extends Eloquent {

    protected $table = 'users';
    public $timestamps = false;

    public function parent()
    {
        return $this->belongsTo('User', 'parent_id');
    }

    public function children()
    {
        return $this->hasMany('User', 'parent_id');
    }

}

and then I could use it in my code like this:

$user     = User::find($id);

$parent   = $user->parent()->first();
$children = $user->children()->get();

Give that a try and let me know how you get on!

Questions:
Answers:

I had a chain of self referencing contracts (a contract can be continued by another contract) and also needed self referencing. Each contract has zero or one previous and also zero or one next contract.

My data table looked like the following:

+------------------+  
| contracts        |  
+------------------+  
| id               |  
| next_contract_id |  
+------------------+  

To define the inverse of a relationship (previous contract) you have to inverse the related columns, that means setting
* foreign key column on the model table
* associated column on the parent table (which is the same table)

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Contract extends Model {

    // The contract this contract followed
    function previousContract()
    {
        // switching id and next_contract_id
        return $this->belongsTo('App\Contract', 'id', 'next_contract_id');
    }

    // The contract that followed this contract
    function nextContract()
    {
        return $this->belongsTo('App\Contract');
        // this is the same as
        // return $this->belongsTo('App\Contract', 'next_contract_id', 'id');
    }
}

See http://laravel.com/docs/5.0/eloquent#one-to-one for further details.