Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concept of laravel first() method

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?

like image 669
fahad shaikh Avatar asked Jun 09 '19 16:06

fahad shaikh


People also ask

What does First () function do in Laravel?

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.

What does First () return in Laravel?

It just returns null.

What is get and first in Laravel?

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.

What is get () in Laravel?

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.


1 Answers

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.

like image 126
Mateus Junges Avatar answered Oct 25 '22 11:10

Mateus Junges