Ad

How To Add Additional Column Relationship In Pivot Table In Laravel

Version: Laravel 5.4

I have 3 Models

Model: Employee

    protected $fillable = ['name'];
    public function emails(){
        return $this->belongsToMany('App\Email')->using('App\EmailEmployee');
    }

Model: Email

    protected $fillable = ['username'];
    public function employees(){
        return $this->belongsToMany('App\Employee')->using('App\EmailEmployee');
    }

Every Employee has many email access and emails allocates to many employees. But I have another column in email_employee table

email_id                    (emails table)
employee_id                 (employees table)
assigned_by                 (employees table)

how to make relation of assigned_by column with employees table

Pivot Model

    use \Illuminate\Database\Eloquent\Relations\Pivot;
    class EmailEmployee extends Pivot{
        public function assignedBy(){
            return $this->belongsTo('App\Employee');
        }
    }

I tried


    $email = Email::find(1);
    dd($email->employee[0]->pivot->assignedBy);

But not working

Ad

Answer

Custom Intermediate Table Model

To solve your problem, you should look to use the ->using() method on the belongsToMany method.

The subsection "Defining Custom Intermediate Table Models" in this link briefly describes this. eloquent-relationships#many-to-many

You basically create a model for the pivot table so that you can define additional relations to it.

You can still access data from Blade and Controllers the way you are now as Laravel will still deal with the relationship for you. However, you can access the pivot table with ->pivot and as you have told laravel to use a model for the pivot table, you can also access all the relationship defined functions from that model.

Example:

Employee

class Employee extends Model
{
protected $fillable = ['name'];
    public function emails(){
        return $this->belongsToMany('App\Email')
        ->using('App\PivotModel');
    }
}

Email

 class Email extends Model
    {
    protected $fillable = ['username'];
        public function employees(){
            return $this->belongsToMany('App\Employee')
            ->using('App\PivotModel');
        }
    }

PivotModel

class EmailEmployee extends Pivot
{
    public function assignedBy(){
            return $this->belongsTo('App\Employee','assigned_by');
        }
}

Be Sure to extend Pivot on the pivot model and not Model

Now you can just do:

$user->emails()->first()->pivot->assignedBy

The reason for the ->first() is that you have a many to many, meaning that you will be getting a collection of emails assigned to the user. You would normally loop through them but for this example, simply selecting the first will do the same.

If you just want the column value and not the relationship value, then add ->withPivot('assigned_by') which will allow you to access the value directly.

If you are wanting to audit when the assignment was made, then you may also want to add ->withTimestamps() if your pivot table has timestamps included, so that you can access those too.

Ad
source: stackoverflow.com
Ad