Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
311 views
in Technique[技术] by (71.8m points)

How to sort Laravel eloquent result by another table column

I have a very simple chat application which have 3 tables users , chat_rooms and chats table for sotring every users messages.

I want to show chat rooms in a box in my view but i want them to be sorted by messages created_at so that the chat rooms that have newest messages be on the top.

the query that i use is

ChatRoom::with('user')
            ->join('chats','chat_rooms.room_id','chats.room_id')
            ->select('chat_rooms.*','chats.created_at as c','chats.message')
            ->orderBy('c','DECS')
            ->paginate(5);

this works fine but returns all chats i tried to use groupBy('room_id') on my query but then it stoped working

i could use collections methods to fix this but then i could not use pagination and i realy dont want to use collection methods in this case.

note that im using laravel 5.4


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your eloquent pagination run on ChatRoom table Not on messages. So you can try another ways to load your message under chatroom.

  • If you have a lot of chatroom and want to paginate both chatroom and their messages, you can paginate chatroom (without join to messages) and run eloquent for each chatroom messages separately.
  • you can also use lazy load for messages on view but you must control messages paginate yourself

-------------EDITED-------------

Show chatroom with new messages:

Laravel <6

ChatRoom::select(['chat_rooms.*', 'chats.created_at as c'])
            ->join(DB::raw("(SELECT chats.room_id, max(chats.created_at) as created_at
                FROM chats
                GROUP BY room_id
                ORDER BY created_at DESC
                ) as chats"), function ($join) {
                $join->on("chat_rooms.id", "=", "chats.room_id");
            })
            ->orderBy('c', 'DECS')
            ->paginate(5);

Laravel >=6

$chatQuery = Chat::selectRaw("chats.room_id, max(chats.created_at) as created_at")
            ->groupBy("chats.room_id")
            ->orderBy("created_at", "desc");

ChatRoom::select(['chat_rooms.*', 'chats.created_at as c'])
  ->joinSub($chatQuery, 'chats', function ($join) {
       $join->on('chat_rooms.id', '=', 'chats.room_id');
  })
  ->orderBy('c','DECS')
  ->paginate(5);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...