Laravel (5.7) Eloquent Many to Many with query on双方

Posted

技术标签:

【中文标题】Laravel (5.7) Eloquent Many to Many with query on双方【英文标题】:Laravel (5.7) Eloquent Many to Many with query on both sides 【发布时间】:2019-04-20 13:07:16 【问题描述】:

假设我有一个用户、角色和一个数据透视表。我为 Role 和 User 设置了 belongsToMany。

用户模型

<?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

我的问题是如何在数据透视表中获取过滤器。

例如:我只想过滤userIdroleId或两者都过滤userId and roleId

如果我在刀片模板中选择user = admin,我想获取用户拥有的所有角色。 预期结果:

username    roleName

admin       Admin
admin       HR
admin       Account

如果我在刀片模板中选择选项role = HR,我想获得该角色拥有的所有用户。 预期结果:

username    roleName

admin       HR
johndoe     HR

如果我选择选项user = adminrole = 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

【问题讨论】:

【参考方案1】:

您可以尝试使用此查询根据您的示例过滤数据。

函数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();

您还可以尝试使用此查询来根据您的示例过滤数据。此查询将为您提供具有您在角色对象中给出的特定角色的用户。 例如:如果您在刀片模板中选择选项角色 = 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();

【讨论】:

你救了我的命。非常感谢。【参考方案2】:

您可以尝试wherePivot()wherePivotIn() 方法:

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

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

【讨论】:

以上是关于Laravel (5.7) Eloquent Many to Many with query on双方的主要内容,如果未能解决你的问题,请参考以下文章

如何查询 Laravel Eloquent 的 belongsTo 关系?

Laravel 5.7 执行 SQL 查询多少次?

php Laravel 5 Eloquent CheatSheet #laravel #eloquent

php Laravel 5 Eloquent CheatSheet #laravel #eloquent

php Laravel 5 Eloquent CheatSheet #laravel #eloquent

php [Eloquent CheatSheet] Eloquent #laravel #eloquent的常见查询方法