Невозможно создать фильтр поиска для ролей, который отображает всех пользователей с выбранной ролью - Laravel

У меня belongsToMany красноречивые отношения между App/Models/User и App/Models/Role. Отношения между пользователем и ролью хранятся в role_user сводной таблице. Я пытаюсь создать фильтр расширенного поиска, который будет отображать мне список пользователей с определенными критериями роли.

Я уже сделал это для критериев электронной почты, т.е. соответствующий пользователь будет отображаться, если электронная почта зарегистрированного пользователя совпадает с вводом. Этого было легко добиться, поскольку столбец электронной почты существует в самой таблице пользователей.

Как я могу добиться того же для критериев роли, которые будут относиться к пользователю через сводную таблицу и будут отображать конечное количество пользователей с выбранной ролью.

введите описание изображения здесь

Приложение / модели / пользователь

public function roles() {
    return $this->belongsToMany(Role::class);
}

Приложение / модели / роль

public function users() {
    return $this->belongsToMany(User::class);
}

Приложение / HTTP / Livewire / UserController

public $filters = [
    'email' => null,
    'role' => ''
];

public function render() {
    $users = User::query() 
        -> when($this -> filters['email'], fn($query, $email) => $query -> where('email', $email))
        -> when($this -> filters['role'], fn($query, $role) => $query -> with('roles') -> where('id', $role))
        -> search('name', $this -> search)
        -> paginate(5);
    $roles = Role::all();
    return view('livewire.user-controller', ['users' => $users, 'roles' => $roles]);
}

ресурсы / представления / livewire / пользователь-контроллер

<!-- Advanced Search -->
<div>
    @if ($showFilters)
    <div>
        <div>
            <x-input.group inline for="filter-email" label="Email">
                <x-input.text wire:model.lazy="filters.email" id="filter-email" placeholder="Enter Email" />
            </x-input.group>
        </div>
        <div>
            <x-input.group inline for="filter-role" label="Role">
                <x-input.select wire:model.lazy="filters.role" id="filter-role" placeholder="Select Role">
                    @foreach($roles as $role)
                    <option value="{{ $role->id }}">{{ $role->name }}</option>
                    @endforeach
                </x-input.select>
            </x-input.group>
        </div>
    </div>
    @endif
</div>

<!-- Users Table -->
<x-table>
    <x-slot name="head">
        <x-table.heading>
            <x-input.checkbox />
        </x-table.heading>
        <x-table.heading>ID</x-table.heading>
        <x-table.heading>Name</x-table.heading>
        <x-table.heading>Email</x-table.heading>
        <x-table.heading>Role</x-table.heading>
    </x-slot>

    <x-slot name="body">
        @foreach($users as $key => $user)
        <x-table.row wire:loading.class.delay="opacity-50">
            <x-table.cell wire:key="row-{{ $user->id }}">
                <x-input.checkbox wire:model="selected" value="{{ $user->id }}" />
            </x-table.cell>
            <x-table.cell>{{ $users->firstitem() + $key }}</x-table.cell>
            <x-table.cell>{{ $user->name }}</x-table.cell>
            <x-table.cell>{{ $user->email }}</x-table.cell>
            <x-table.cell>
                @foreach($user->roles as $role)
                {{ $role->name }}
                @endforeach
            </x-table.cell>
        </x-table.row>
        @endforeach
    </x-slot>
</x-table>

person ToxifiedHashkey    schedule 01.12.2020    source источник
comment
Вы можете использовать whereHas с функцией обратного вызова для фильтрации результатов запроса на основе отношения. laravel.com/docs/8.x/   -  person miken32    schedule 02.12.2020
comment
@ miken32 Пожалуйста, не могли бы вы быть более наглядными, не могли бы вы помочь мне с кодом, так как я застрял в одном и том же месте уже 4 дня, я знаю, что это может быть глупо, но я очень новичок в Laravel. Я ценю вашу помощь!   -  person ToxifiedHashkey    schedule 02.12.2020


Ответы (1)


Чтобы получить всех пользователей, у которых есть роль с идентификатором 5

//Say this role id (5) is received as a result of user selecting a role from select
$roleId = 5; 

$users = User::whereHas('roles', function($query) use($roleId) {
    return $query->where('id', $roleId);
});

Спасибо за ответ, не могли бы вы мне помочь, заставив его работать в формате запроса. User :: query () - ›when ($ this -› filters ['role'], fn ($ query, $ role) = ›$ query -› with ('roles') - ›where ('id', $ role)), так как мне нужно связать его вместе с состоянием функции, чтобы обнаруживать запрос, когда ($ this - ›filter ['role']. Спасибо за ваше время.

User::query()
  ->when(
    $this->filters['role'], 
    fn($query, $role) => $query->whereHas(
        'roles', 
        fn($query) => $query->where('id', $role)
    )
)
person Donkarnash    schedule 01.12.2020
comment
Спасибо за ответ, не могли бы вы мне помочь, заставив его работать в формате запроса. User::query()->when($this -> filters['role'], fn($query, $role) => $query -> with('roles') ->where('id', $role)), поскольку мне нужно связать его вместе с состоянием функции для обнаружения запроса when($this -> filters['role']. Спасибо за уделенное время. - person ToxifiedHashkey; 02.12.2020
comment
Как я пытался, я получаю ошибки, так как я не строю и не связываю отношения в запросе должным образом. - person ToxifiedHashkey; 02.12.2020
comment
@ToxifiedHashkey Обновили ответ, пожалуйста, проверьте и дайте мне знать, что это работает для вас - person Donkarnash; 02.12.2020