Reputation: 197
When I try to write an admin rule to prevent users to enter certain route I get this error: Property [name] does not exist on this collection instance.
User Model
<?php
public function roles()
{
return $this->belongsToMany(Role::class, 'role_user', 'user_id', 'role_id');
}
public function isAdmin()
{
if ($this->roles->name == "Admin") {
return true;
}
return false;
}
Admin Middleware
public function handle($request, Closure $next)
{
if (Auth::check()) {
if (Auth::user()->isAdmin()) {
return $next($request);
}
}
return redirect('/');
}
Routes and Controller
Route::group(['middleware' => 'admin'], function ()
{
Route::get('/home', 'HomeController@index')->name('home');
});
public function __construct()
{
$this->middleware('admin');
}
Upvotes: 0
Views: 65
Reputation: 4499
$this->roles
returns a Collection
instance. so you can't access a property from a collection. That is the error.
In this scenario You only need to know that this user is an admin or not. So you don't have to fetch all the roles to do that. And doing that is less efficient too.
So the best solution is use exists()
function.
public function isAdmin()
{
// is there a role which name is admin.
if ($this->roles()->where('name', 'Admin')->exists()) {
return true;
}
return false;
}
Upvotes: 2
Reputation: 1678
The roles()
relationship on the model is for many-to-many, so calling $this->roles
returns a collection of models, not a single model instance. If you want to check if Admin
is one of the roles that the current user has, try something like this:
public function isAdmin()
{
if ($this->roles->pluck('name')->contains('Admin')) {
return true;
}
return false;
}
The pluck()
method returns a "column" of data from your collection (in this case the name field) as a new collection. The contains()
method searches the collection for the given value, and returns true if the collection contains the value, or false if it does not.
https://laravel.com/docs/5.7/collections#available-methods
Upvotes: 2