Reputation: 1641
First of all I apologise for the title, I could not find anything better.
In my project I have Users and Groups. Users can join a group and create a group. The relationships are defined as follows.
User Model
/** Get all the groups the user is administrator of
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function groupsAdmin()
{
return $this->hasMany('App\Group','group_admin_id','id');
}
Group Model
/** Get the users in a group
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function users()
{
return $this->belongsToMany(\App\User::class,'groups_users', 'group_id','user_id');
}
What I am trying to do is get all the users who have joined the groups created by an user. For that I have written a method in my User model:
/**
* Returns all the users who have attended groups created by this user
*/
public function getPastGroupAttendees()
{
// first verify if the user is admin of any group
if(!$this->groupsAdmin)
{
return false;
}
$attendees = array();
foreach($this->groupsAdmin as $group)
{
if(count($group->users) > 0) $attendees[] = $group->users;
}
return $attendees;
}
But the problem with this method is its slow and will get slower with new data. And also as a user can join multiple groups, I would get duplicate users from this method. So if anyone can show me some directions to optimize and correct this it would be very helpful.
Upvotes: 2
Views: 1661
Reputation: 163788
You can setup two relations in User
model:
public function groupsAdmin()
{
return $this->hasMany('App\Group', 'group_admin_id', 'id');
}
public function groups()
{
return $this->belongsToMany('App\Group');
}
It's one-to-many for admin and many-to-many for groups and users (you'll need pivot table here).
To load the data, use eager loading:
$groupWithUsers = Group::where('group_admin_id', $adminId)->with('users')->first();
$groupsOfUsers = User::with('groups')->get();
To remove duplicates you can iterate over groups and merge()
all users collections into one and then use unique()
method to remove duplicates.
Another way to do it is to create model for pivot table and get all users of the group with simple and readable code:
$groups = Group::where('group_admin_id', $adminId)->pluck('id'); // Get IDs of groups.
UserGroup::whereIn('group_id', $groups)->get()->unique(); // Get unique users from these groups.
Upvotes: 1