简体   繁体   English

Laravel嵌套关系在哪里

[英]Laravel nested relationship where

I am building a system that has users. 我正在建立一个有用户的系统。 Users have roles and roles have actions. 用户具有角色,角色具有动作。 My models are setup like so: 我的模型设置如下:

User 用户

/**
 * The roles that belong to the user.
 *
 * @return Object
 */
public function roles()
{
    return $this->belongsToMany('App\Models\User\Role')->withTimestamps();
}

Role 角色

/**
 * The actions that belong to the role.
 *
 * @return Object
 */
public function actions() 
{
    return $this->belongsToMany('App\Models\User\Action')->withPivot('path');
}

/**
 * The users that belong to the role.
 *
 * @return Object
 */
public function users()
{
    return $this->belongsToMany('App\Models\User\User');
}

Action 行动

/**
 * The roles that belong to the action.
 *
 * @return Object
 */
public function roles() 
{
    return $this->belongsToMany('App\Models\User\Role');
}

I am trying search the users actions using the following: 我正在尝试使用以下内容搜索用户操作:

$user->whereHas('roles.actions', function($query) use ($id, $path, $method){ 
        $query->where('user.id', $id);
        $query->where('action.path', $path);
        $query->where('action.method', $method);
})->get();

However, for some reason the object returned is empty (no rows returned). 但是,由于某种原因,返回的对象为空(没有返回行)。 If I remove the $query->where('action.path', $path); 如果我删除$query->where('action.path', $path); it works, but that is pointless because I need that part. 它有效,但是那毫无意义,因为我需要那部分。

The SQL that gets generated is: 生成的SQL是:

select * from `user` 
    where `user`.`cust_id` = 1 
    and (
            select count(*) from `role` 
            inner join `role_user` on `role`.`id` = `role_user`.`role_id` 
            where `role`.`cust_id` = 1 
            and `role_user`.`user_id` = `user`.`id` 
            and 
            (
                select count(*) from `action` 
                inner join `action_role` on `action`.`id` = `action_role`.`action_id` 
                where `action`.`cust_id` = 1 
                and `action_role`.`role_id` = `role`.`id` 
                and `user`.`id` = 1 
                and `action`.`path` = '/admin/users/administrators/{id}/changePassword' 
                and `action`.`method` = 'GET' 
                and `action`.`cust_id` = 1
            ) >= 1 
            and `role`.`cust_id` = 1
        ) >= 1

My users table contains the following data: 我的用户表包含以下数据:

id    cust_id    name
1     1          John Smith

My action table contains the following data: 我的操作表包含以下数据:

id    cust_id    path                                               method
1     1          /admin/users/administrators/{id}/changePassword    GET

Why is this not working? 为什么这不起作用?

I don't really understand how that's a valid query because you are querying on a column in the users table in the subquery which is not joining on anything pertaining to users. 我真的不明白这是一个有效的查询,因为您正在查询子查询中的users表中的一列,该列未加入与用户有关的任何内容。

Try this instead. 试试这个吧。

$user->whereHas('roles.actions', function($query) use ( $path, $method){
    $query->where('path', $path);
    $query->where('method', $method);
})->find($id);

remove ->withPivot('path'); 删除->withPivot('path'); and try again 然后再试一次

As noted in your question, and the other one HERE path is NOT an extra attribute of your pivot table action_role - holding the relationship between models Role and Action . 如您的问题所述,另外一个HERE path不是数据透视表action_role的额外属性-保持模型RoleAction之间的关系。

Instead it's an attribute of the action table. 相反,它是action表的属性。 Hence, using withPivot('path') you're defining that extra attribute on the pivot (ie action_role ) that doesn't exist and therefore is not at all necessary. 因此,使用withPivot('path')可以在pivot上定义不存在的额外属性(即action_role ),因此根本不需要。

Regarding the empty set you get if you include the line $query->where('action.path', $path) , the most probable reason is that incorrect OR null value is provided in your $path variable. 关于空集你,如果你有行$query->where('action.path', $path)最可能的原因是不正确null值在您提供的$path变量。 Double check to see if it has the right value. 仔细检查是否具有正确的值。


Note: As far as I know, you can't execute whereHas on the $user like that (although I'm not quite sure what it holds). 注意: 据我所知,您不能像这样在$user上执行whereHas (尽管我不太确定它的whereHas )。 Even if the $user is a collection of users ( obtained by App\\Models\\User::all() ), the appropriate approach to using whereHas is to use it on a model like App\\User::whereHas(... or a along with a relation. 即使$user$user集合( App\\Models\\User::all() ),使用whereHas的合适方法是在诸如App\\User::whereHas(...或一个关系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM