Bappy
Bappy

Reputation: 111

Laravel(5.6) eloquent order by last message

I have a User model which has a reference to MessageParticipant model (returns all the message subjects the user participating in)

public function messages()
{
 return $this->hasMany(MessageParticipant::class);
}

The MessageParticipant refers to a MessageSubject model (returns the message subject participants belong to)

public function message_subject()
{
    return $this->belongsTo(MessageSubject::class);
}

The MessageSubject model refers to a Message model (return all the messages within message subject)

public function messages()
{
    return $this->hasMany(Message::class);
}

I want to return all the message subjects a user is participating in, ordering according to latest message entry to the message subject. Below is what I've tried so far.

$messages = $user->messages()->search($search)
                    ->join('messages', 'messages.message_subject_id', '=', 'message_subject.id')
                    ->select('message_subject.*', 'messages.created_at AS latest_message_at')
                    ->orderByDesc('latest_message_at')
                    ->paginate(30);

How can I do it?

Upvotes: 0

Views: 427

Answers (1)

Jonas Staudenmeir
Jonas Staudenmeir

Reputation: 25906

You can use a BelongsToMany relationship to get the message subjects directly:

class User extends Model {
    public function messageSubjects() {
        return $this->belongsToMany(MessageSubject::class, 'message_participants');
    }
}

Then use it with a modified withCount() to get the latest message:

$messages = $user->messageSubjects()
    ->withCount(['messages as latest_message' => function($query) {
        $query->select(DB::raw('max(messages.created_at)'));
    }])
    ->search($search)
    ->orderByDesc('latest_message')
    ->paginate(30);

Upvotes: 3

Related Questions