skip to Main Content

So I have a many-to-many table with created_at and the foreign keys student_id and status_id.

For each student, I want to retrieve an entry only if the latest one has status_id = 1.

I tried it like this: (it’s a chain of queries, in this case $query would be Student::where(something else))

$query->whereHas('statusuri', function($query) use ($statusuri) {
                $query->latest('status_student.created_at')->where('status_id', 1);
});

(statusuri is the many-to-many relationship)

but I get a different result from what I need.

It does the where clause first and then latest(). Basically, it retrieves the last entry which matches the where.

I want to search for each student, the latest entry and if the where clause matches it, get that entry. If not, don’t return anything.

Is that possible with Eloquent?

Thanks.

2

Answers


  1. Have you considered a "has one of many" relationship : https://laravel.com/docs/9.x/eloquent-relationships#advanced-has-one-of-many-relationships

    You can make a relationship in your Student model:

    public function latestStatus()
    {
        return $this->hasOne(StatusStudent::class)->ofMany([
            'created_at' => 'max',
            'id' => 'max',
        ], function ($query) {
            $query->where('status_id', 1);
        });
    }
    

    Edit: works only for Laravel 8+

    Login or Signup to reply.
  2. In your case, you can use the where and latest methods together in a subquery, like this:

    $query->whereHas('statusuri', function($query) use ($statusuri) {
        $query->where(function($query) {
            $query->where('status_id', 1)
                  ->latest('status_student.created_at');
        });
    });
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search