Laravel finally has higher level orWhere for query scopes
Laravel's excellent querybuilder and Eloquent ORM is handy as ever. But with newer version of laravel, it's much more simpler. 5.8 is here already and this feature has not been talked as much because it seems a minor feature release. Let's dive in with an example :
<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Role;
class User extends Authenticatable
{
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/*
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = ['deleted_at'];
/**
* Scope a query to only filter admin users.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeAdmin($query)
{
return $query->where('role', Role::Admin);
}
/**
* Scope a query to only filter reviewer users.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeReviewer($query)
{
return $query->where('role', Role::Reviewer);
}
/**
* Scope a query to only filter customer users.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeCustomer($query)
{
return $query->where('role', Role::Customer);
}
}
The use case is, we want to get the users who are either has admin
or reviewer
role.
For earlier versions of laravel(version < 5.8), we would do :
$users = App\User::admin()->orWhere(function (Builder $query) {
$query->reviewer();
})->get();
There is nothing difficult in above eloquent query but having a closure just to filter a scope for an orWhere clause seems too much sometimes. But that case is no more valid after 5.8 releases. Now we can do :
$users = App\User::admin()->orWhere->reviewer()->get();
And that's it. It's a very small change but makes the code much more simpler to implement and read. Sometimes you might get lost in the closures when the query is large. Features like this makes it much more comfortable to implement.