Laravel (5.7) Eloquent Many To Many With Query On Both Sides
Say I have a users, roles, and a pivot table. I have belongsToMany set up for both Role and User.
User Model:
<?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();
}
}
Role Model:
<?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();
}
}
Table "Users":
userId username
1 admin
2 johndoe
3 menghour
Table "Roles":
roleId roleName
1 Admin
2 HR
3 Account
Pivot Table "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
My question is how I can get filter in pivot table.
For example: I want to filter only userId
or roleId
or both userId and roleId
if I select user = admin
in blade template, I want to get all roles that user have.
expected result:
username roleName
admin Admin
admin HR
admin Account
if I select option role = HR
in blade template,, I want to get all user that role have.
expected result:
username roleName
admin HR
johndoe HR
if I select option user = admin
and role = HR
, I want to get only specific user and role.
expected result:
username roleName
admin HR
I've tired:
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();
note: I'm using Laravel 5.7
Answer
You could try this query to filter data as per your example.
The function whereHas
is used to retrieve all the users with a given role. To get the roles of user you have to use with
function.
$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();
You could also try this query to filter data as per your example. This query will give you the user with particular that role which has you given in roles object. For Example: if you select option role = HR in blade template.
$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();
Related Questions
- → "failed to open stream" error when executing "migrate:make"
- → October CMS Plugin Routes.php not registering
- → OctoberCMS Migrate Table
- → OctoberCMS Rain User plugin not working or redirecting
- → October CMS Custom Mail Layout
- → October CMS - How to correctly route
- → October CMS create a multi select Form field
- → October CMS - Conditionally Load a Different Page
- → How to disable assets combining on development in OctoberCMS
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → OctoberCms component: How to display all ID(items) instead of sorting only one ID?
- → In OctoberCMS how do you find the hint path?
- → How to register middlewares in OctoberCMS plugin?