Laravel (5.7) красноречивый вопрос «многие ко многим» с запросом с обеих сторон - PullRequest
0 голосов
/ 17 ноября 2018

Скажем, у меня есть пользователи, роли и сводная таблица. Мне принадлежит принадлежит, настроенная как на роль, так и на пользователя.

Модель пользователя :

<?php

namespace App;

...
use App\Models\Role;

class User extends Authenticatable
{
  ...
  public function roles()
  {
    return $this->belongsToMany(Role::class, "UserRoles", "userId", "roleId")
                ->withPivot("read", "write", "update", "delete")
                ->withTimestamps();
  }
}

Ролевая модель :

<?php

namespace App\Models;

...
use App\User;

class Role extends Model
{
  ...
  public function users()
  {
    return $this->belongsToMany(User::class, "UserRoles", "roleId", "userId")
                ->withPivot("read", "write", "update", "delete")         
                ->withTimestamps();
  }

}

Таблица «Пользователи» :

userId username
1      admin
2      johndoe
3      menghour

Таблица «Роли» :

roleId roleName
1      Admin
2      HR
3      Account

Сводная таблица "UserRoles" :

id     userId   roleId   read   write   update   delete
1      1        1        1      1       1        1
2      1        2        1      1       1        1
3      1        3        1      1       1        1
4      2        2        1      0       0        0
5      3        3        1      1       1        0

У меня вопрос, как мне получить фильтр в сводной таблице.

Например : я хочу фильтровать только userId или roleId или оба userId and roleId

если я выберу user = admin в шаблоне блейда, я хочу получить все роли, которые есть у пользователя. ожидаемый результат:

username    roleName

admin       Admin
admin       HR
admin       Account

если я выберу опцию role = HR в шаблоне блейда, я хочу, чтобы все пользователи имели эту роль. ожидаемый результат:

username    roleName

admin       HR
johndoe     HR

если я выберу опцию user = admin и role = HR, я хочу получить только определенного пользователя и роль. ожидаемый результат:

username    roleName

admin       HR

Я устал:

User::whereHas("roles", function ($query) use ($request) {
      if ($request->userId) {
        $query->where("userRoles.userId", "=", $request->userId);
      }
      if ($request->roleId) {
        $query->where("userRoles.roleId", "=", $request->roleId);
      }
    })->get();

примечание: я использую Laravel 5.7

Ответы [ 2 ]

0 голосов
/ 18 ноября 2018

Вы можете попробовать этот запрос для фильтрации данных в соответствии с вашим примером.

Функция whereHas используется для получения всех пользователей с данной ролью.Чтобы получить роли пользователя, вы должны использовать функцию with.

$user = User::whereHas('roles', function ($query) use ($request) {
            if ($request->roleId) {
                $query->where("userRoles.roleId", "=", $request->roleId);
            }
        })
        // It will give you the user's role data.
        ->with('roles');

// It will check in users table if you have applied the filter by user.
if ($request->userId) {
    $user = $user->where("users.id", "=", $request->userId);
}

$user = $user->get();

Вы также можете попробовать этот запрос для фильтрации данных в соответствии с вашим примером.Этот запрос предоставит вам пользователя с определенной ролью, которую вы дали в объекте ролей.Например: если вы выберете опцию role = HR в шаблоне блэйда.

$user = User::whereHas('roles', function ($query) use ($request) {
        if ($request->roleId) {
            $query->where("userRoles.roleId", "=", $request->roleId);
        }
    })
    // It will give you the user data with a particular given role which you has passed in the request.
    ->with(['roles' => function($query) use($request) {
        if ($request->roleId) {
            $query->where("roles.id", "=", $request->roleId);
        }
    }]);

// It will check in users table if you have applied the filter by user.
if ($request->userId) {
    $user = $user->where("users.id", "=", $request->userId);
}

$user = $user->get();
0 голосов
/ 17 ноября 2018

Вы можете попробовать методы wherePivot() или wherePivotIn():

User::roles()->wherePivot('roleId',$request->roleId)
    ->wherePivot('userId',$request->userId)
    ->get()

https://laravel.com/docs/5.7/eloquent-relationships#many-to-many

...