sql >> Base de Datos >  >> RDS >> Mysql

laravel elocuente ordenar por relación

Según mi conocimiento, carga ansiosa with el método ejecuta la segunda consulta. Es por eso que no puedes lograr lo que quieres con carga ansiosa with método.

Creo que usar join método en combinación con método de relación es la solución La siguiente solución está completamente probada y funciona bien.

// 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();
}

Luego puede llamar a $user->sortedChannels('desc') para obtener la lista de canales ordenar por respuestas created_at atributo.

Para condiciones como canales (que puede o no tener respuestas), simplemente use leftJoin método.

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

Editar:

Si desea agregar groupBy método a la consulta, debe prestar especial atención a su orderBy cláusula. Porque en Sql naturaleza, Group By la cláusula se ejecuta primero antes de Order By cláusula. Consulte los detalles de este problema en esta pregunta de desbordamiento de pila .

Entonces, si agrega groupBy método, tienes que usar orderByRaw y debe implementarse de la siguiente manera.

return $this->channels()
                ->leftJoin('replies', 'channels.id', '=', 'replies.channel_id')
                ->groupBy(['channels.id'])
                ->orderByRaw('max(replies.created_at) desc')
                ->get();