[英]Laravel Eloquent filter relationship by last pivot record
我有3个表: user
, role
和数据透视表user_role
。 用户和角色之间存在多对多关系。
还有一个细节,每个分配(角色到用户)在user_role
表中都有timestamp
,因此我可以找到最近为用户添加的角色。
是否有可能编写雄辩的查询来获取最近分配了角色的所有用户,例如id = 5?
我需要以某种方式从按timestamp
排序的pivot
获取最后一条记录,然后在whereHas
语句中使用它。 但是如何获得最后的记录呢?
谢谢您的回答。 但是我想使这一切变得更加复杂。 如果我们添加表system
,现在将是system
和user
之间的一对多关系,那么用户可以属于一个系统,并且系统可以有多个用户。
现在,如何获取例如system
ID,其中包含具有ID = 5(在开始时)的最后一个角色的用户。
首先,您需要确保您的关系中包含枢纽时间戳记:
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;
您可以将枢轴列添加到您的关系中,如下所示:
/**
* 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();
}
编辑:尝试这样的事情。
$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的用户一样,获取具有至少一个这些用户之一的系统。
这给出了user_role
表中按timestamp
列排序的最后一个用户。
$user->roles()->withPivot('timestamp')->orderBy('user_role.timestamp','desc')->first();
更新:
$users=User::with(['system','role'=>function($query)
{
$query->orderBy('pivot_timestamps','desc');
}])->get();
然后,这将提供数据透视表中按时间戳排序的所有用户的系统ID。
foreach($users as $user)
{
$user->system->id;
}
确保您与withPivot.
在用户和角色模型方面有关系withPivot.
这样您就可以使用pivot_timestamps
return $this->belongsToMany('users')->withPivot('timestamps');
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.