Reputation:
I have a small Laravel app with several users and different roles.
What I want is to have a different page to display the users according to their roles (a page to see the admins, a page to see the students etc...)
I have a Users table
(of course), a Roles table
and a role_user table
Roles :
Schema::create('roles', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
role_user table :
Schema::create('role_user', function (Blueprint $table) {
$table->id();
$table->BigInteger('role_id')->unsigned()->onDelete('cascade');
$table->BigInteger('user_id')->unsigned()->onDelete('cascade');
$table->timestamps();
});
I know that it will seem easy to a lot of you, but not to me. I'm stuck...
Thanks a lot !
Upvotes: 0
Views: 1139
Reputation:
Thank you all for your answers.
I finally found an answer to my question (I did not see your posts before...)
This is what I do :
public function admins()
{
$adminRole = Role::where('name', 'admin')->first();
$admins = $adminRole->users;
return view('admin.users.admins', compact('admins'));
}
It works fine but if there's a better way, I'd be happy to learn it ;)
Thank you all.
Peace
Upvotes: 0
Reputation: 1130
You don't really need a link table for user roles. It can be done much easier with just a Roles
table. Let me explain:
First you can make a migration for the roles table. I assume you already have that table but if not, this is how you can create one
php artisan make:migration create_roles_table
And you can fill in the fields accordingly. To make the relation with the user you need to add a role function to the user model. So in your user model you can say
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function role()
{
return $this->belongsTo(Role::class);
}
In your Roles model you can do the same but the other way around. If you not already have a Roles model you can easily create one using php artisan make:model Roles
. You can add this to the Roles model to make the relation complete:
public function users()
{
return $this->hasMany(User::class);
}
Assuming you want multiple users with the same role the above is the correct way
As last you need to add a role_id field to the user to make the relation complete. You can do this by adding $table->integer('role_id')
to your user migration.
If all set and done you can do something like $user->role->name
to get the name of the role (Assuming you have a field called name in your roles table) and you can add different rules accordingly. For instance using middleware
You can create a middleware for this exact reason. php artisan make:middleware name
And you can do something like this
class RoleAllowedMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$allowed_ids =[1,2];
if(!in_array($request->user()->role_id, $allowed_ids)) {
return redirect('/');
}
return $next($request);
}
}
To make certain routes only accessible for users with a specific role
I hope this is what you are looking for!
Upvotes: 2
Reputation: 61
You can maintain a one to many relationships between roles and users by adding these two methods in their model files.
User.php
public function roles() {
return $this->belongsToMany('App\Models\Role', 'role_user');
}
Role.php
public function users()
{
return $this->belongsToMany('App\Models\User', 'role_user');
}
So, you can then simply fetch all the users belonging to that particular role by using something like Role::find(1)->users;
Upvotes: 0
Reputation: 12218
you can do it using double join:
$roleName = 'admin';
$adminUsers = DB::table('users')->join('role_user', 'users.id', 'role_user.user_id')
->join('roles', 'role_user.role_id', 'roles.id')
->where('roles.name', $roleName)->get();
or the better solution is using laravel many to many relation
after building the relation like in doc, you can do it using whereHas:
$adminUsers = User::whereHas('roles', function ($query) use ($roleName) {
$query->where('roles.name', $roleName);
})->get();
Upvotes: 0