У меня 3 модели
модельные отношения
user есть belongsToMany('App\Channel'); channel имеет hasMany('App\Reply', 'channel_id', 'id')->oldest(); скажем, у меня есть 2 канала – канал-1 – канал-2
  channel-2 имеет последние ответы, чем channel-1 
теперь я хочу заказать канал пользователя по текущему ответу своего канала. точно так же, как приложение для чата. как я могу заказать канал пользователя именно так?
Я уже пробовал некоторые коды. но ничего не происходит
 // User Model public function channels() { return $this->belongsToMany('App\Channel', 'channel_user') ->withPivot('is_approved') ->with(['replies']) ->orderBy('replies.created_at'); // error } // also public function channels() { return $this->belongsToMany('App\Channel', 'channel_user') ->withPivot('is_approved') ->with(['replies' => function($qry) { $qry->latest(); }]); } // but i did not get the expected result 
EDIT также, я пробовал это. да, я получил ожидаемый результат, но он не будет загружать весь канал, если нет ответа.
 public function channels() { return $this->belongsToMany('App\Channel') ->withPivot('is_approved') ->join('replies', 'replies.channel_id', '=', 'channels.id') ->groupBy('replies.channel_id') ->orderBy('replies.created_at', 'ASC'); } 
РЕДАКТИРОВАТЬ:
 
 
 
По моим сведениям, нетерпеливая загрузка методом запускает второй запрос. Вот почему вы не можете достичь того, чего хотите, с энергичной загрузкой методом.
  Я думаю, что метод join в сочетании с методом отношений является решением.  Следующее решение полностью протестировано и работает хорошо. 
 // 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(); } 
  Затем вы можете вызвать $user->sortedChannels('desc') чтобы получить список заказов каналов , created_at атрибут created_at . 
  Для таких условий, как каналы (которые могут иметь или не иметь ответов), просто используйте метод leftJoin . 
 public function sortedChannels($orderBy) { return $this->channels() ->leftJoin('replies', 'channel.id', '=', 'replies.channel_id') ->orderBy('replies.created_at', $orderBy) ->get(); } 
Редактировать:
  Если вы хотите добавить метод groupBy в запрос, вы должны обратить особое внимание на свой orderBy .  Поскольку в природе Sql предложение Group By выполняется сначала перед предложением Order By .  См. Подробно эту проблему в этом вопросе stackoverflow . 
  Поэтому, если вы добавляете метод groupBy , вы должны использовать метод orderByRaw и должны быть реализованы следующим образом. 
 return $this->channels() ->leftJoin('replies', 'channels.id', '=', 'replies.channel_id') ->groupBy(['channels.id']) ->orderByRaw('max(replies.created_at) desc') ->get(); 
Во-первых, вам не нужно указывать имя сводной таблицы, если вы следуете соглашению об именах Laravel, чтобы ваш код выглядел немного чище:
 public function channels() { return $this->belongsToMany('App\Channel') ... 
  Во-вторых, вам нужно будет вызвать join явно для достижения результата в одном запросе: 
 public function channels() { return $this->belongsToMany(Channel::class) // a bit more clean ->withPivot('is_approved') ->leftJoin('replies', 'replies.channel_id', '=', 'channels.id') // channels.id ->groupBy('replies.channel_id') ->orderBy('replies.created_at', 'desc'); }