Northify
Northify

Reputation: 391

Laravel - Ordering a collection of models

I have 3 Models that I'm grouping together into 1 collection. This works great but I need to somehow order them by date. Something like orderByRaw('term_date DESC')

public function allRequests()
    {
        // Collect all request types
        $requests = collect();
        $terms = $this->terminations;
        $deacs = $this->loadeactivations;
        $reacs = $this->loareactivations;

        // Use push() to collect them all in one collection
        foreach ($terms as $term)
            $requests->push($term);
        foreach ($deacs as $deac)
            $requests->push($deac);
        foreach ($reacs as $reac)
            $requests->push($reac);

        return $requests;
    }

The problem is each model has a different orderby field name that I need to order them from.

$termination needs to orderby term_date
$loareactivation needs to orderby reactivation_date $loadeactivation needs to orderby deactivation_date

The way the collection is now it is listed by the oder the the models are grouped together.

I'm trying to figure out a way to take the 3 model dates, cast them into one date and then order them DESC

Any idea how this can be done?

Upvotes: 1

Views: 692

Answers (2)

Arthur Samarcos
Arthur Samarcos

Reputation: 3299

You can pass a callback and check the model for it's class, returning the appropriate ordering field.

return $requests->sortByDesc(function($model) {
    if($model instanceof \App\Terminations){
        return $model->term_date;
    } elseif($model instanceof \App\LoadedReactivation) {
        return $model->reactivation_date;
    } 

    return $model->deactivation_date;
});

Upvotes: 1

mdexp
mdexp

Reputation: 3567

If you plan to do that with collections only (and not a database level), you can think to put an accessor on each model that would return the correct date value based on the model type.
In this way you can uniform the field where you will find the date for the sorting order and simplify your code.

For example:

Termination Model

public function getSortDateAttribute()
{
   return $this->term_date;
} 

LoaReactivation Model

public function getSortDateAttribute()
{
   return $this->reactivation_date;
} 

LoaDeactivation Model

public function getSortDateAttribute()
{
   return $this->deactivation_date;
} 

Then in your function, after you pushed all your records:

return $requests->sortByDesc('sort_order');

Upvotes: 0

Related Questions