#php #mysql #laravel #orm #eloquent
#php #mysql #laravel #orm #eloquent
Вопрос:
У меня есть 3 таблицы: user
, role
и сводная user_role
. Между пользователем и ролью существует взаимосвязь «многие ко многим».
И еще одна деталь: каждое назначение (роль пользователю) есть timestamp
в user_role
таблице, поэтому я могу найти, какая роль была недавно добавлена для пользователя.
Есть ли возможность написать запрос eloquent, чтобы получить всех пользователей, которым недавно назначена роль, например, id = 5?
Мне нужно как-то получить последнюю запись из pivot
ordered by timestamp
, а затем использовать ее в whereHas
инструкции. Но как получить эту последнюю запись?
Редактировать
Спасибо за ваши ответы. Но я хотел бы сделать все это немного сложнее. Что, если мы добавим таблицу system
, и теперь между system
и user
будет отношение один ко многим, поэтому пользователь может принадлежать одной системе, а система может иметь несколько пользователей.
И теперь, как получить, например, идентификатор system
, который содержит пользователей, имеющих последнюю роль с id = 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;
Ответ №2:
Вы можете добавить сводные столбцы в свое отношение, например, так :
/**
* The roles that belong to the user.
*/
public function roles()
{
return $this->belongsToMany('AppRole')->withPivot('timestamp');
}
Затем, если вы хотите проверить, есть ли у пользователя определенная роль в последнее время, я бы сделал это
public function hasRecentRole($roleId, $howRecently = 'last week')
{
return $this->roles()->where('id', $roleId)->wherePivot('timestamp', '>', new CarbonCarbon($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, затем получите систему, в которой есть хотя бы один из этих пользователей.
Комментарии:
1. Возможно ли получить последнюю запись из сводной записи, упорядоченную по метке времени внутри метода из модели? Итак, я смогу сделать это: System::(‘users.lastRole, function($ q){…}). Это работает для меня, но теперь у меня есть ‘users.roles’, и это дает мне все роли, которые я могу запросить путем закрытия, но теперь мне просто нужно иметь ‘users.lastRole’.
Ответ №3:
Это дает последнему пользователю упорядоченный по timestamp
столбцу из user_role
таблицы.
$user->roles()->withPivot('timestamp')->orderBy('user_role.timestamp','desc')->first();
Обновить:
$users=User::with(['system','role'=>function($query)
{
$query->orderBy('pivot_timestamps','desc');
}])->get();
затем это дает системный идентификатор всех пользователей, упорядоченных по временным меткам в сводной таблице.
foreach($users as $user)
{
$user->system->id;
}
Убедитесь, что у вас есть отношения в user и role model withPivot.
, чтобы вы могли использовать pivot_timestamps
return $this->belongsToMany('users')->withPivot('timestamps');
Комментарии:
1. Возможно ли получить последнюю запись из сводной записи, упорядоченную по метке времени внутри метода из модели? Итак, я смогу сделать это: System::(‘users.lastRole, function($ q){…}). Это работает для меня, но теперь у меня есть ‘users.roles’, и это дает мне все роли, которые я могу запросить путем закрытия, но теперь мне просто нужно иметь ‘users.lastRole’.