Reputation: 645
How can I use orderBy to order by a model's method?
Consider the model User and the method
public function fullName() {
return $this->firstName . $this->lastName;
}
I want to do something like orderBy('fullName'). Is this possible? I know I can make equivalent code using Query Builder, but I want to keep my Model methods as they are.
Upvotes: 2
Views: 9449
Reputation: 1
$personas = Persona::select('*');
$personas = $personas->addSelect(DB::raw('concat(nombre,\' \',apellido1,\' \',apellido2) as fullname'))
->orderBy('fullname', 'ASC')->paginate(K_LINEAS_X_PAGINA);
I couldn't make it work without the select('*')
Upvotes: 0
Reputation: 645
I've solved the problem with this solution:
$sorted = User::get()
->sortBy('full_name') //appended attribute
->pluck('id')
->toArray();
$orderedIds = implode(',', $sorted);
$result = DB::table('user')
->orderByRaw(\DB::raw("FIELD(id, ".$orderedIds." )"))
->paginate(10);
I've appended fullName attribute to the model, to be used by sortBy. With this solution I was able to use orderBy to order by an appended attribute of the model, exactly what I wanted to do. So yes, it is possible. And also I was able to use pagination. Thanks to all who tried to help.
Upvotes: 1
Reputation: 1856
I think you have a few options here:
fullName
. Then change your model to use the view.If you go with option 2, first define an attribute:
public function getFullNameAttribute()
{
return $this->firstName . $this->lastName;
}
Then using Laravel's Collection:
$items = Model::all()->sortBy('FullName');
Note: The default option for sortBy
is ascending, so if you wish to sort descending:
$items = Model::all()->sortByDesc('FullName');
You can read more about accessors here: https://laravel.com/docs/5.7/eloquent-mutators#defining-an-accessor
Upvotes: 4