Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

laravel eloquente classificar por relacionamento


De acordo com meu conhecimento, carga ansiosa with método executa a 2ª consulta. É por isso que você não consegue o que deseja com carregamento antecipado with método.

Acho que usar join método em combinação com método de relacionamento é a solução. A solução a seguir é totalmente testada e funciona bem.
// In User Model
public function channels()
{
    return $this->belongsToMany('App\Channel', 'channel_user')
        ->withPivot('is_approved');
}

public function sortedChannels($orderBy)
{
    return $this->channels()
            ->join('replies', 'replies.channel_id', '=', 'channel.id')
            ->orderBy('replies.created_at', $orderBy)
            ->get();
}

Então você pode chamar $user->sortedChannels('desc') para obter a lista de canais ordem por respostas created_at atributo.

Para condições como canais (que pode ou não ter respostas), basta usar leftJoin método.
public function sortedChannels($orderBy)
    {
        return $this->channels()
                ->leftJoin('replies', 'channel.id', '=', 'replies.channel_id')
                ->orderBy('replies.created_at', $orderBy)
                ->get();
    }

Editar:

Se você deseja adicionar groupBy para a consulta, você deve prestar atenção especial ao seu orderBy cláusula. Porque em Sql nature, Group By cláusula é executada primeiro antes de Order By cláusula. Veja detalhes deste problema em esta pergunta do stackoverflow .

Então, se você adicionar groupBy método, você deve usar orderByRaw e deve ser implementado como o seguinte.
return $this->channels()
                ->leftJoin('replies', 'channels.id', '=', 'replies.channel_id')
                ->groupBy(['channels.id'])
                ->orderByRaw('max(replies.created_at) desc')
                ->get();