问题
I have the following models in my application
- User
- Group
- Task
which have the following relationships
- User and Group have a many-to-many relationship
- Task and Group have a many-to-many relationship
So basically a user can belong to more than one group and each group can have more than one task.
Following is the table structure.
users
- id
- name
groups
- id
- name
tasks
- id
- name
group_user
- id
- group_id (foreign key with groups table)
- user_id (foreign key with users table)
group_tasks
- id
- group_id (foreign key with groups table)
- task_id (foreign key with tasks table)
Now I want to retrieve all the tasks for the user.
I tried the following approaches and both didn't work.
Approach 1
$user->groups()gives the list of groups for a user$group->tasks()gives the list of tasks for a group
So I tried
$user->groups()->tasks() but it didn't work.
Approach 2
I tried Has Many Through by adding this to my User model
public function tasks()
{
return $this->hasManyThrough(Task::class, Group::class);
}
but even that didn't work. The following is the error that I am getting
QueryException in Connection.php line 713:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'groups.user_id' in 'field list' (SQL: select `tasks`.*, `groups`.`user_id` from `tasks` inner join `groups` on `groups`.`id` = `tasks`.`group_id` where `groups`.`user_id` = 1)
My guess is that this is happening because it is expecting one-to-many relationship, but I have a many-to-many relationship.
So is there a way to retrieve it without getting all groups and then looping through them?
回答1:
User Model
public function groups()
{
return $this->belongsToMany('App\Group');
}
Group Model
public function tasks()
{
return $this->belongsToMany('App\Task');
}
Task Model
public function groups()
{
return $this->belongsToMany('App\Group');
}
Retrieving all tasks for a user.
$user = User::find(1);
$user->load('groups.tasks');
$tasks = $user->groups->pluck('tasks')->collapse();
回答2:
You can also take a look at the extension of the HasManyThrough here: https://github.com/staudenmeir/eloquent-has-many-deep
It helps you to retrieve many sub-levels of your relationships. In your case, it would be User -> belongsToMany(Groups) -> blongsToMany (Tasks) just add your method to the user model like:
public function tasks()
{
return $this->hasManyDeep(
'App\Task',['App\Group']
);
}
来源:https://stackoverflow.com/questions/38138290/retrieve-distant-relation-through-has-many-through-for-many-to-many-relation-in