user2424495
user2424495

Reputation: 592

Laravel retrieve multiple relationships

I have a laravel project where a User can have many Client class. The Client can have many Session and and a Session can have many Assessment and many Plan. I am using hasManyThrough on the Client to get Assessment and Plan. Each Assessment and Plan has a review_date timestamp saved into the database.

What I'd like to do is get all the Assessment and Plan for any Client with their review_date as today. Ideally something like:

$events = Auth::user()->reviews()->today();

What I don't know how to do it make the reviews function, because it's essentially combining 2 relationships.

Can anyone help me out?

User.php

public function clients()
{
    return $this->hasMany(Client::class);
}

public function assessments()
{
    return $this->hasManyThrough(Assessment::class, Client::class);
}

public function plans()
{
    return $this->hasManyThrough(Plan::class, Client::class);
}

public function reviews()
{
    // return all assessments and plans
}

public function scopeToday(Builder $query)
{
    $query->whereDate('review_date', Carbon::today());
}
Client.php

public function assessments()
{
    return $this->hasManyThrough(Assessment::class, Session::class);
}

public function plans()
{
    return $this->hasManyThrough(Plan::class, Session::class);
}
Session.php

public function assessments()
{
    return $this->hasMany(Assessment::class);
}

public function plans()
{
    return $this->hasMany(Plan::class);
}

Upvotes: 0

Views: 162

Answers (1)

miken32
miken32

Reputation: 42755

You can get a collection from both methods, so you could simply merge the 2 together. (Be warned, this will lead to ugly code later when you have to check object types during the loop.) You can't chain the scope method, since you aren't getting back a relationship object, but you could pass the date as a parameter instead, or just fix it at today's date if you'll never need other dates.

public function reviews(Carbon $date)
{
    return $this
        ->assessments()
        ->whereDate('review_date', $date)
        ->get()
        ->toBase()
        ->merge(
            $this->plans()->whereDate('review_date', $date)->get()->toBase()
        )
        ->sortBy('review_date');
}

And then call it like this:

$date = now();
$events = Auth::user()->reviews($date);

Upvotes: 1

Related Questions