weeniebeenie's avatar

Can get first record from ManyToMany but not last? Undefined method.

I have a standard ManyToMany relationship with a pivot. show, song and show_song. In the song model I have the relationship with an orderBy:

    public function shows()
    {
        return $this->belongsToMany(Show::class)->orderBy('date');
    }

Depending on the record this relationship could return up to around 1500 rows so I don't want to ever return them all at once, I can paginate.

$paginated = $song->shows()->paginate();

That's fine, but above the paginated results I also want to display the very first and last record

$song->shows()->first()

Works to get the first record but

$song->shows()->last()

Doesn't work, returns Call to undefined method Illuminate\Database\Eloquent\Relations\BelongsToMany::last()

So how can I get the last record from the M2M model without having to get the whole ~1500 results first? If I do $song->shows->last() that returns the full collection and then finds the last.

All I've come up with so far is to remove the orderBy from the M2M method and then do it twice. Once to paginate, get the first record off the paginated results and then again in reverse to get the last.

$paginated = $song->shows()->orderBy('date')->paginate();

$first = $paginated->first();

$last = $song->shows()->orderBy('date', 'desc')->first();

But that feels a little messy. Is there a cleaner way?

0 likes
3 replies
tykus's avatar
tykus
Best Answer
Level 104

There is no last Builder method; but you can use latest record according to any given column like this:

$latest = $song->shows()->latest('date')->first();

Please or to participate in this conversation.