【问题标题】:Laravel use a pivot field to filter polymorphic many to many relationshipLaravel 使用枢轴字段过滤多态多对多关系
【发布时间】:2020-07-15 12:26:39
【问题描述】:

我正在使用多态多对多关系将用户权限附加到几个不同的模型 - 数据透视表称为 permissables

Permissables
- id
- user_id
- permissable_type
- permissable_id
- role
- created_at
- updated_at

这运行良好 - 我可以使用以下方法为我的 Project 模型返回允许用户列表:

public function users()
{
    return $this->morphToMany(User::class, 'permissable')->withPivot('role')->withTimestamps();
}

如果我想将其过滤给所有者 - 即枢轴字段 role 等于 owner - 我可以在 Tinker 中执行以下操作:

Project::first()->users->where('pivot.role', '=', 'owner')

但如果我在我的模型中尝试这个:

public function owners()
{
    return $this->users()->where('pivot.role', '=', 'owner');
}

当我在 Tinker 中调用 Project->owners 时,出现错误:

>>> Project::first()->owners
[!] Aliasing 'Project' to 'App\Project' for this Tinker session.
Illuminate/Database/QueryException with message 'SQLSTATE[HY000]: General error: 1 no such column: pivot.role (SQL: select "users".*, "permissables"."permissable_id" as "pivot_permissable_id", "permissables"."user_id" as "pivot_user_id", "permissables"."permissable_type" as "pivot_permissable_type", "permissables"."role" as "pivot_role", "permissables"."created_at" as "pivot_created_at", "permissables"."updated_at" as "pivot_updated_at" from "users" inner join "permissables" on "users"."id" = "permissables"."user_id" where "permissables"."permissable_id" = 1 and "permissables"."permissable_type" = App/Project and "pivot"."role" = owner)'

【问题讨论】:

    标签: php laravel eloquent


    【解决方案1】:

    对于第一个问题:

    return $this->users->where('pivot.role', '=', 'owner');
    

    此行有效,因为$this->users 返回用户的带有枢轴的集合(键名称为pivot)。而您正在使用where-method 过滤用户collection

    第二个问题:

    $this->users() 将 laravel 代码更改为原始 sql,如:

    select users.*, permissables.permissable_id as pivot_permissable_id, permissables.user_id as pivot_user_id, permissables.permissable_type as pivot_permissable_type, permissables.role as pivot_role, permissables.created_at as pivot_created_at, permissables.updated_at as pivot_updated_at
    from users 
    inner join permissables on users.id = permissables.user_id 
    where permissables.permissable_id = 1 and permissables.permissable_type = "App/Project"
    

    所以中间表名称是permissables,而不是pivot。将where('pivot.role', 'owner')应用到users()时mysql找不到中间的列。

    Laravel 提供wherePivot 方法,它会为你添加中间表名。

    public function owners()
    {
        return $this->users()->wherePivot('role', 'owner'); // change to where pemissables.role = 'owner'
    }
    

    【讨论】:

      猜你喜欢
      • 2021-08-12
      • 1970-01-01
      • 1970-01-01
      • 2019-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-25
      相关资源
      最近更新 更多