How to Sort Related Model Data?

Asked

Viewed 173 times

2

I have the following relationship in my application:

Model Client:

class Cliente extends Model
{
    protected $table = 'clientes';

    public function Usuario(){ 
        return $this->hasMany('App\Models\Admin\Usuario', 'id_cliente');
    }    
}

Model User:

class Usuario extends Model
{
    protected $table = 'usuarios';

    public function Cliente(){ 
        return $this->belongsTo('App\Models\Admin\Cliente', 'id_cliente'); 
    }
}

But I need to sort the results when I call all customer users in my view:

@foreach($Cliente->Usuario as $usuario)...

This is just an example, I have several relationships in my application that I need to apply this sort filter, as I can do this?

1 answer

4


In Laravel it is possible to pre-load the results of the relationships of a particular model. Thus, along with this upload, you can also add conditions that will be applied to the relationships that will be loaded along with your query. This is done through the method with (Whenever you want to use it, it should be the first method to be called).

In the controller, you can do so:

$with['usuarios'] = function ($query) {
    return $query->orderBy('nome');
};

$cliente = Cliente::with($with)->find($id);

Or you can also separate the two, and make a second query for users based on the client query.

 $cliente = Cliente::find($id);

 $usuarios = $cliente->usuarios()->orderBy('nome')->get();

In the second example, you would have to do the foreach in $usuarios.

Ordering the collection

It is also possible to sort the relationship data after the conclusion of the query.

For example, I want to sort my users who are related to a customer by name. And then I want to list them again and order them by the update date.

Instead of making two queries, you can do so:

#controller

 $cliente = Cliente::with('usuarios')->find($id);

 $ordenadores['nome'] = function ($usuario)
 {
      return $usuario->nome;
 };

 $ordenadores['atualizacao'] = function ($usuario)
 {
        return $usuario->created_at;
 };

 return view('minha_view', compact('cliente', 'ordenadores'));

There in the view, you can do so:

#view

@foreach($cliente->usuarios->sortBy($ordenadores['nome']) as $usuario)

@endforeach


@foreach($client->usuarios->sortBy($ordenadores['atualizacao']) as $usuario)

@endforeach

Note: In some cases, it is not necessary to use a Callback in the sortBy. Just pass the name of the field as an argument sortBy, to sort the data in the Collection.

@foreach($client->usuarios->sortBy('created_at') as $usuario)

@endforeach

Tip

Generally, to maintain the readability of your model’s methods, I suggest using singular for relationships (one to one) as belongsTo and hasOne, and plural for hasMany or belongsToMany and related (multiple relationships).

  • very good bro, actually sent a go that glue and worked up without making the modifications in the controller, just putting the name of the field I wanted to sort on "sortBy". ->sortBy('name'). Thank you very much msm!

  • 1

    @Raylansoares forgot to mention that internally the Laravel already does this (turns the key into callback) to use in sortBy.

  • For a lot of show bro

  • 1

    If you need it, you also have the sortByDesc('nome')

Browser other questions tagged

You are not signed in. Login or sign up in order to post.