本文介绍了Laravel 5雄辩的hasManyThrough / belongsToManyThrough关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Laravel 5.2应用程序中,我有三种模型: User Role Task
一个用户与多个 Roles 和一个 Role 与多个 Tasks 相关联。
因此,每个用户通过其角色都与多个任务相关联。

In a Laravel 5.2 application I have three models: User, Role and Task. A User is associated with multiple Roles, and a Role is associated with multiple Tasks. Therefore each user is associated to multiple tasks, through their roles.

我正尝试访问所有 Tasks 通过其角色与用户关联。

I am trying to access all Tasks associated with a User, through their Roles.

我模型的相关部分如下:

The relevant parts of my models look like:

class User extends Authenticatable
{    
    public function roles()
    {
        return $this->belongsToMany('App\Role');
    }

    public function tasks()
    {
        return $this->hasManyThrough('App\Task', 'App\Role');
    }
}

class Role extends Model
{
    public function tasks()
    {
        return $this->belongsToMany('App\Task');
    }

    public function users()
    {
        return $this->belongsToMany('App\User');
    }
}

class Task extends Model
{    
    public function roles()
    {
        return $this->belongsToMany('App\Role');
    } 
}

以下返回SQL错误;

The following returns an SQL error;

Column not found: 1054 Unknown column 'roles.user_id'

似乎正在尝试通过角色模型中的(不存在)外键而不是通过数据透视表访问关系。

It seems to be trying to access the relationship through a (non-existent) foreign key in the Role model, rather than through the pivot table.

$user = Auth::user;
$tasks = $user->tasks;

如何通过这些关系访问与用户相关的所有任务?

How can I access all tasks related to a user through these relationships?

推荐答案

我已经开发了,这可能会让您感兴趣。您将需要添加新的关系类(如我的要点所述;太长了,无法在此处粘贴),并且还按照要点中的描述覆盖了基础 Model 类来实现 belongsToManyThrough

I have developed a custom BelongsToManyThrough relationship which might interest you. You would need to add the new relation class (as given in my gist; it is too long to paste here), and also override your base Model class as described in the gist to implement belongsToManyThrough.

然后(假设您使用的是Laravel的默认表命名方案,如果没有,则可以指定以及联接表),您可以将关系定义为:

Then (assuming you are using Laravel's default table naming schemes - if not, you can specify the joining tables as well), you would define your relationship as:

public function tasks()
{
    return $this->belongsToManyThrough(
        'App\Task',
        'App\Role');
}

belongsToManyThrough 不会只会为您提供用户的任务列表,还会告诉您每个用户通过其执行每个任务的角色。例如,如果您有:

belongsToManyThrough will not only give you a list of Tasks for your User(s), it will also tell you the Role(s) via which each User has each Task. For example, if you had:

$ user-> tasks()-> get()

输出类似于:

 [
    {
        "id": 2,
        "name": "Ban spammers",
        "roles_via": [
            {
                "id": 2,
                "slug": "site-admin",
                "name": "Site Administrator",
                "description": "This role is meant for \"site administrators\", who can basically do anything except create, edit, or delete other administrators."
            },
            {
                "id": 3,
                "slug": "group-admin",
                "name": "Group Administrator",
                "description": "This role is meant for \"group administrators\", who can basically do anything with users in their same group, except other administrators of that group."
            }
        ]
    },
    {
        "id": 13,
        "name": "Approve posts",
        "roles_via": [
            {
                "id": 3,
                "slug": "group-admin",
                "name": "Group Administrator",
                "description": "This role is meant for \"group administrators\", who can basically do anything with users in their same group, except other administrators of that group."
            }
        ]
    },
    {
        "id": 16,
        "name": "Reboot server",
        "roles_via": [
            {
                "id": 2,
                "slug": "site-admin",
                "name": "Site Administrator",
                "description": "This role is meant for \"site administrators\", who can basically do anything except create, edit, or delete other administrators."
            }
        ]
    }
]

我的与涉及 foreach 的其他解决方案相比,自定义关系只需几个查询就能高效地完成此任务,而其他解决方案会创建问题。

My custom relationship does this efficiently, with only a few queries, as opposed to other solutions involving foreach, which would create an n+1 query problem.

这篇关于Laravel 5雄辩的hasManyThrough / belongsToManyThrough关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-11 08:26