首页 文章

Laravel Eloquent按最后一个枢轴记录过滤关系

提问于
浏览
1

我有3个表: userrole 和pivot user_role . 用户和角色之间存在多对多关系 .

还有一个细节,每个作业(用户角色)在 user_role 表中都有 timestamp ,所以我可以找到最近为用户添加了什么角色 .

是否有可能编写一个雄辩的查询来获取 recently 分配角色的所有用户,例如id = 5?

我需要以某种方式从 timestamp 订购 pivot 获取最后一条记录,然后在 whereHas 语句中使用它 . 但如何获得最后的记录?

编辑

谢谢您的回答 . 但我想让它变得更加复杂 . 如果我们添加表 system 现在将是 systemuser 之间的一对多关系怎么办,所以用户可以属于一个系统,系统可以有多个用户 .

现在,如何获得例如 system 的id,其中包含具有id = 5的最后一个角色的用户(如开头) .

3 回答

  • 2

    您可以为您的关系添加数据透视列,如下所示:

    /**
     * The roles that belong to the user.
     */
    public function roles()
    {
        return $this->belongsToMany('App\Role')->withPivot('timestamp');
    }
    

    然后,如果你想检查用户最近是否有特定角色,我会这样做

    public function hasRecentRole($roleId, $howRecently = 'last week')
    {
         return $this->roles()->where('id', $roleId)->wherePivot('timestamp', '>', new Carbon\Carbon($howRecently))->count();
    }
    

    EDIT: 尝试这样的事情 .

    $systems = System::whereHas('users', function ($query) {
        $query->whereHas('roles', function ($query) {
            $query->where('id', 5)
                ->whereRaw('timestamp = (select max(`timestamp`) from user_roles WHERE user_id = role_user.user_id'));
        });
    })->get();
    

    如果没有,也许你应该分步工作 . 就像获得具有最新角色5的用户一样,获得至少具有这些用户之一的系统 .

  • 1

    首先,您需要确保您的关系包括透视时间戳:

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

    然后,您可以在代码中使用以下查询来获取最近收到特定角色的所有用户(例如id = 5) .

    $role = Role::with(['users', function($query) {
        $query->orderBy('pivot_created_at', 'DESC');
    }])->find(5);
    
    // all users with (role_id = 5) ordered by (user_role.created_at DESC)
    $users = $role->users;
    
  • 1

    这给出了 user_role 列中 timestamp 列所排序的最后一个用户 .

    $user->roles()->withPivot('timestamp')->orderBy('user_role.timestamp','desc')->first();
    

    Update:

    $users=User::with(['system','role'=>function($query)
    {
       $query->orderBy('pivot_timestamps','desc');
    }])->get();
    

    然后,这给出了在数据透视表中按时间戳排序的所有用户的系统ID .

    foreach($users as $user)
    {
          $user->system->id;
    }
    

    确保您在用户和角色模型 withPivot. 中有关系,以便您可以使用 pivot_timestamps

    return $this->belongsToMany('users')->withPivot('timestamps');
    

相关问题