The laravel first()
method is pretty straight forward and that's why this question might be silly, but I am not understanding the use of first()
method.
Actually, I'm following a youtube tutorial where I am authenticating a user if he has the role of admin
then only he will get the access of route
otherwise will be redirected to home
.
There is no error or issue with code but my understanding.
I am returning the user in User
model class function if the user has the role passed by the middleware
Route
Route::get('admin', function (){
return 'This is Admin page';
})->middleware(['auth', 'auth.admin']);
Middleware
public function handle($request, Closure $next)
{
if (Auth::user()->hasAnyRole('admin'))
{
return $next($request);
}
return redirect('home');
}
User Modal
public function hasAnyRole($role)
{
return null !== $this->roles()->where('name', $role)->first();
}
If I use first()
method in hasAnyRole
function then only route
is protected by other users and only admin
get access to the route,
If I remove the first()
method then all the users get access to route
which I don't understand why?
The first() method will return only one record, while the get() method will return an array of records that you can loop over. Also, the find() method can be used with an array of primary keys, which will return a collection of matching records.
It just returns null.
get method give a collection and first method give you a model instance. When you want to get collection of data means, lots of results then use get but if you want to retrieve only one result then use first.
Basically what you need to understand is that get() return a collection(note that one object can be in the collection but it still a collection) why first() returns the first object from the result of the query(that is it returns an object) #Take_away Get() return a collection first() return an object.
According to the docs:
The first method returns the first element in the collection that passes a given truth test:
collect([1, 2, 3, 4])->first(function ($value, $key) {
return $value > 2;
});
// 3
You may also call the first method with no arguments to get the first element in the collection. If the collection is empty, null is returned:
collect([1, 2, 3, 4])->first();
// 1
In your question, if you don't use the first()
method, it will return a collection with no data, like:
Roles {#1
[]
}
This empty collection is not equals to null
.
About the !==
operator
$x !== $y
It the previous snippet, it returns true if $x is not equal to $y, or they are not of the same type.
So, in your code:
return null !== $this->roles()->where('name', $role)->first();
it will return true
if (and only if) the user doesn't have the required role, what you get done by the first()
method:
$this->roles()->where('name', 'admin')->first();
If the user doesn't have the admin
role, then it returns null
, what is identical and same type of null
(in your comparison). So it returns false
, cause null !== null
returns false, and the access is not granted.
If you use something like
$this->roles()->where('name', 'admin');
and the user does not have the admin
role, it return something like this:
Roles {#1
[]
}
Now your hasAnyRole
function returns true
and the access is granted to the user, since the empty collection is not of the same type and also not equals to null
;
Docs about the first
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With