Pregunta

I have 3 tables: users, pools, permissions. Users and Pools have a pivot table since they have a many-to-many relationship.

Permission entries are created by me only manually. Then, each pool can assign permissions to their own users as they see fit. Therefore, the pivot table for linking users to permissions needs to have both pool_id and user_id and permission_id

So how does this pivot table work? How do I make a three-way pivot table?

EDIT: My question is basically asked here, with no satisfactory answer!

¿Fue útil?

Solución

For pivot table linking 3 models you need additional data send when attaching models like in this answer: Laravel - Pivot table for three models - how to insert related models?:

$model->relation()->attach($otherModel, ['thirdModelKeyName' => 'thirdModelKeyValue']);

You can create custom relation class, say ThreeBelongsToMany, that will extend belongsToMany and override attach() method.

Then override belongsToMany() method on your models, that are involved in such relation (or use a Trait there) to return mentioned custom relation class instead of generic belongsToMany when applicable.

The attach() method could look like this:

public function attach($id, array $attributes = array(), $touch = true, $otherId = null)
{
    if ( ! is_null($otherId))
    {
        if ($otherId instanceof Model) $otherId = $otherId->getKey();

        $attributes[$this->getThirdKey()] = $otherId;
    }

    return parent::attach($id, $attributes, $touch);
}

Also you can use some helpers to fetch those related models, like for example (key names should be obtained with methods for flexibility, they are hard coded to make it short):

/**
 * Accessor for far related model (thru pivot)
 *
 * @return mixed
 */
public function getTrackAttribute()
{
    if (is_null($this->pivot)) return null;

    if (is_null($this->pivot->track_id)) return null;

    return ($this->pivot->track) ?: $this->pivot->track = Track::find($this->pivot->track_id);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top