В laravel отношение «многие ко многим», как в примере с документацией Laravel. https://laravel.com/docs/9.x/eloquent-relationships#many-to-many
users
id - integer
name - string
roles
id - integer
name - string
role_user
user_id - integer
role_id - integer
В модели пользователей у меня есть
public function roles()
{
return $this->belongsToMany(Role::class);
}
В модели ролей у меня есть
public function users()
{
return $this->belongsToMany(User::class);
}
Как я могу получить все роли, к которым я не имею отношения.
Я пробовал что-то вроде
$this->availableRoles = Role::doesntHave('users')->get();
Но это дает мне всю роль, которой нет ни у одного пользователя.
Любой намек на это.
🤔 А знаете ли вы, что...
PHP поддерживает объектно-ориентированное программирование.
Если у вас уже есть экземпляр User
(я предполагаю, что это и есть $this
?), вы можете просто отфильтровать отношение:
$this->availableRoles = Role::whereDoesntHave('users', function ($subQuery) {
return $subQuery->where('users.id', $this->id);
})->get();
Это должно вернуть все элементы Role
, если только эта роль не связана с User
($this
, $user
, auth()->user()
и т. д.; при необходимости отрегулируйте).
Альтернативный подход: отфильтровать роль на основе существующих ролей:
$this->availableRoles = Role::whereNotIn('id', $this->roles->pluck('id'))->get();
Этот подход получает roles.id
для User
экземпляра.
Вы можете взглянуть на эффективность запроса и использовать тот, который работает лучше всего, но любой подход должен работать нормально.
Примечание. Если $this
не является экземпляром User
, настройте:
$user = User::find($userId); // or `auth()->user()`, etc.
$availableRoles = Role::whereDoesntHave('users', function ($subQuery) use ($user) {
return $subQuery->where('users.id', $user->id);
})->get();
// OR
$availableRoles = Role::whereNotIn('id', $user->roles->pluck('id'))->get();