首页 > 解决方案 > 无法为角色创建搜索过滤器,该过滤器显示具有所选角色的所有用户 - Laravel

问题描述

我在和之间有着belongsToMany雄辩的关系。用户和角色之间的关系存储在数据透视表中。我正在尝试创建一个高级搜索过滤器,它将向我显示特定角色条件下的用户列表。App/Models/UserApp/Models/Rolerole_user

我已经为电子邮件标准完成了此操作,即如果注册用户的电子邮件与输入匹配,则将显示相关用户。这很容易实现,因为电子邮件列存在于用户表本身中。

我如何才能为角色标准实现相同的目标,这将通过数据透视表与用户相关,并显示具有所选角色的最终用户数。

在此处输入图像描述

应用程序/模型/用户

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

应用程序/模型/角色

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

应用程序/Http/Livewire/用户控制器

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>

标签: laraveleloquentlaravel-8

解决方案


检索具有 id 为 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)) 因为我需要将它与函数的状态绑定以检测请求 when($this -> filters['role']。谢谢你的时间。

User::query()
  ->when(
    $this->filters['role'], 
    fn($query, $role) => $query->whereHas(
        'roles', 
        fn($query) => $query->where('id', $role)
    )
)

推荐阅读