0

How can i order by attributes on a subdocument (lazy-loaded from belongsTo relation)?

I have:

Message::with(['conversation'])
->where(.....)
->get()

This returns:

[
{
       "_id": "5aee075893782d1b1f460b13",
        ......
        "updated_at": "2018-05-05 19:34:48",
        "created_at": "2018-05-05 19:34:48",
  "conversation": {
            "_id": "5aee075793782d1b1f460b12",
            "updated_at": "2018-05-06 12:21:23",
            "created_at": "2018-05-05 19:34:47",
            "messageCount": 5
        }
}
]

I now need to order (the messages) by updated_at in conversation. I have tried ->orderBy('conversation.updated_at','desc'), but with no luck. I am guessing that the problem is that the conversation object is not available to orderBy due to lazy-loading...

Daniel Valland
  • 1,057
  • 4
  • 21
  • 45

1 Answers1

0

Add this relation to the Message::class

public function conversationLatestFirst(): HasMany
{
    return $this->hasMany(Conversation::class)->orderByDesc('created_at');
}

Then you should be able to query by

Message::with(['conversationLatestFirst'])
->where(.....)
->get()
Quezler
  • 2,376
  • 14
  • 29
  • This is great, but not quite what I meant... The message is related to a conversation with a belongsTo, and so there is only one conversation the message is related to, but each conversation has an updated_at attribute, and I need to order the messages by the updated_at attribute of the conversation it is related to... That is, message->conversation->updated_at ... If not nested I could do Message...->orderBy('updated_at','desc'), but since it is nested, I cannot access the attribute in the orderBy, which is why I tried something like >orderBy('conversation.updated_at','desc') but not working. – Daniel Valland May 06 '18 at 15:29
  • My bad, replace conversation and message in my example and vice versa, and yes, orderBy does not work 'outside' of relations, but inside them they most definately (should) work, since the last time i checked – Quezler May 06 '18 at 16:18
  • I dont quite see how that would work, all I need is to order the outer collection (messages) on an attribute that exists in the embdedded document of each message (conversation->updated_at), but I dont see how to make that available to the orderBy of the outer collection... In other words, I need the messages in order in which their conversation was updated.... – Daniel Valland May 06 '18 at 16:36