I have three models: Group, Activity, User. With the following relationships in the models.
Activities
belongTo aGroup
(with thegroup_id
being a field in the
activity)Users
belongTo aGroup
(with thegroup_id
being a field in the user)- Likewise the
Group
hasManyActivities
and also hasManyUsers
.
Users and Activities are each only associated with one group.
I want to find the users for a particular activity (via the common group). I don’t think this is a hasManyThrough relation – Eloquent complains that there isn’t a group.activity_id
How should I define the relationship between Activities and Users who share a common group_id, so that I can get the list of users for a given activity?
Group
name:string
Activity
name: string
group_id: int
User
name: string
group_id: int
class Group extends Model
{
public function activities(): HasMany
{
return $this->hasMany(Activity::class);
}
public function users(): HasMany
{
return $this->hasMany(User::class);
}
}
class User extends Model
{
public function group(): BelongsTo
{
return $this->belongsTo(Group::class);
}
}
class Activity extends Model
{
public function group(): BelongsTo
{
return $this->belongsTo(Group::class);
}
public function users(): HasManyThrough
{
return $this->hasManyThrough(User::class, Group::class);
}
}
2
Answers
Thanks @IGP, that was an excellent description of what goes on behind the scenes and I'm sure it would work.
@gych from Laracasts also answered with this, which uses the existing relations to make it really efficient:
You can use a
HasMany
relationship to return a collection of models based on the query it generates with the relationship method’s parameters.You’re not strictly forced to user foreign keys and primary keys when using Eloquent Relationships. It’s just a (very sensible) convention.
For
Activity
->User
, it’s very straightforward.In this case the generated SQL should be something like
Your
HasManyThrough
throws an error because it expects a different structure than what you have.For it to work your relationships should have been
User
hasManyGroup
Group
hasManyActivity
User
hasManyThroughActivity
(usingGroup
as intermediate table).