Laravel 5 雄辩的 hasManyThrough/belongsToManyThrough 关系

2023-03-04php开发问题
10

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

问题描述

在 Laravel 5.2 应用程序中,我有三个模型:UserRoleTask.一个User关联多个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.

我正在尝试通过他们的角色访问与 User 关联的所有 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('AppRole');
    }

    public function tasks()
    {
        return $this->hasManyThrough('AppTask', 'AppRole');
    }
}

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

    public function users()
    {
        return $this->belongsToMany('AppUser');
    }
}

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

以下返回SQL错误;

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

它似乎试图通过 Role 模型中的(不存在的)外键访问关系,而不是通过数据透视表.

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?

推荐答案

我开发了一个自定义BelongsToManyThrough 关系,您可能会感兴趣.您需要添加新的关系类(在我的要点中给出;粘贴在这里太长了),并且还需要按照要点中的描述覆盖您的基本 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(
        'AppTask',
        'AppRole');
}

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 的解决方案,后者会创建一个 n+1 查询 问题.

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 关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

The End

相关推荐

PHP实现DeepL翻译API调用
DeepL的翻译效果还是很强大的,如果我们要用php实现DeepL翻译调用,该怎么办呢?以下是代码示例,希望能够帮到需要的朋友。 在这里需要注意,这个DeepL的账户和api申请比较难,不支持中国大陆申请,需要拥有香港或者海外信用卡才行,没账号的话,目前某宝可以...
2025-08-20 php开发问题
168

PHP通过phpspreadsheet导入Excel日期数据处理方法
PHP通过phpspreadsheet导入Excel日期,导入系统后,全部变为了4开头的几位数字,这是为什么呢?原因很简单,将Excel的时间设置问文本,我们就能看到该日期本来的数值,上图对应的数值为: 要怎么解决呢?进行数据转换就行,这里可以封装方法,或者用第三方的...
2024-10-23 php开发问题
287

mediatemple - 无法使用 codeigniter 发送电子邮件
mediatemple - can#39;t send email using codeigniter(mediatemple - 无法使用 codeigniter 发送电子邮件)...
2024-08-23 php开发问题
11

Laravel Gmail 配置错误
Laravel Gmail Configuration Error(Laravel Gmail 配置错误)...
2024-08-23 php开发问题
16

将 PHPMailer 用于 SMTP 的问题
Problem with using PHPMailer for SMTP(将 PHPMailer 用于 SMTP 的问题)...
2024-08-23 php开发问题
4

关于如何在 GoDaddy 服务器中使用 PHPMailer 设置 SMTP 的问题
Issue on how to setup SMTP using PHPMailer in GoDaddy server(关于如何在 GoDaddy 服务器中使用 PHPMailer 设置 SMTP 的问题)...
2024-08-23 php开发问题
17