Given $id
is the ID of the user performing the call, the SQL query that we are looking for looks something like this:
SELECT * FROM events WHERE group_id IN (
SELECT group_id FROM group_user WHERE user_id = $id
);
So if in your group_user
table, we find that the user with user_id = 1
has the following group relations group_id = [1, 2, 3, 4, 5]
, the resulting query looks like this: SELECT * FROM events WHERE group_id IN [1, 2, 3, 4, 5];
which are what we are looking for (the events related to those groups).
- Open up
vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php
Insert the following code after the hasMany
method.
/**
* Define a many-through-many relationship.
*
* @param string $related
* @param string $through
* @param string $pivotTable
* @param string $pivotKey
* @param string $pivotThroughKey
* @param string|null $firstKey
* @param string|null $secondKey
* @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
*/
public function manyThroughMany($related, $through, $pivotTable, $pivotKey, $pivotThroughKey, $firstKey = null, $secondKey = null)
{
$relatedModel = new $related; // App\Event
$relatedTable = $relatedModel->getTable(); // events
$firstKey = $firstKey ?: $this->getForeignKey(); // event_id
$throughModel = new $through; // App\Group
$throughTable = $throughModel->getTable(); // groups
$secondKey = $secondKey ?: $throughModel->getForeignKey(); // group_id
return $relatedModel
->whereIn($secondKey, function ($query) use ($pivotTable, $pivotKey, $pivotThroughKey)
{
return $query
->from($pivotTable)
->where($pivotKey, '=', $this->id)
->select($pivotThroughKey);
})
->select($relatedTable . '.*');
}
Now for your model. To use the many-through-many
relation, go to your User
model and add the following.
public function events()
{
return $this->manyThroughMany('App\Event', 'App\Group', 'group_user', 'user_id', 'group_id');
}
The parameters are as follows:
- The name of the target model you are interested in (i.e.
App\Event
).
- The name of the secondary model you need to pass through (i.e.
App\Group
).
- The name of the pivot table (i.e.
group_user
).
- The pivot table key referencing the current model (i.e.
user_id
).
- The pivot table key referencing the secondary model (i.e.
group_id
).
Disclaimers
I don't really know if there's such a thing as a many-through-many relationship, or what the name for it is. This is just the code that worked for me, so I wanted to share it with people who might have the same dilemma as I did.
If there is a simpler way of doing it, please answer! If there are things I can improve, please comment. Thanks.