Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

EnthusiasticLearner's avatar

How to use parent and child relation as constrain on grandchild?

Forgive me if the title is not clearly stated. I have this particular problem (perhaps due to the initial design of the database relation). Is it possible to use the columns in parent together with the columns in child ( via eager load with([]) ) as a constrain to the grand-child?

I have 3 tables. Let's call them

  1. Records
  2. Progress
  3. Routine

The relation between them are as follows:

  1. Records (hasMany)-> Progress
  2. Progress (belongsTo)-> Records
  3. Progress (hasMany)-> Routine

There is no direct relation between Records and Routine. It can be said that Routine are just logs.

In order to retrieve Routine for specific Records. Routine must use two parent relation, 1 column (Routine.Serial) matches with Progress another column (Routine.Date) matches with Records.

I was able to eager load (or Lazy Load) Records and Progress. However I couldn't do so to eager load Routine below Progress with additional constrain from Records

How can I use the "Date" in Records and "Serial" in Progress as constrain to retrieve Routine via eager loading.

If it's impossible, then I'll have to run into the N+1 query problem as I have to lookup for each Progress in order to retrieve the Routine.

p/s: Is there any 'preview' function before I open discussion?

0 likes
6 replies
AhimbisibweRoland's avatar

I think you can also eager load the routine relation when loading the progress

something along the lines of

Records::with("progress.routine")
2 likes
EnthusiasticLearner's avatar

Well, I could load the Routine via eager load the Progress, however it'll return ALL the data (it's a lot), so I need additional constraint (or filters) by "Date" from Records

AhimbisibweRoland's avatar

Well.. I think you can add constraits on your eager loads, something along the lines of

$users = App\Record::where()->with(['progress' => function ($query) {
//add the constraits her
    $query->where('');
}])->get();

1 like
EnthusiasticLearner's avatar

I have tried this, I could only add constrain from the child to grand-child, but not constrain from parent to grand-child.

edoc's avatar

First of all, I am sorry if I mistakenly understand your question.

Did you know you can use hasManyThrough?

on your Record class

public function routines()
    {
        return $this->hasManyThrough('App\Routine', 'App\Progress');
    }

and you can do something like

App\Record::with(['routines' => function($q) {
   //your constraint here
   $q->
}]);

@it.admin

further reading https://laravel.com/docs/5.4/eloquent-relationships#has-many-through

2 likes
EnthusiasticLearner's avatar

@edoc

I haven't looked into hasManyThrough.

Thanks for the heads up. By the look at it in the documentation. It allows Records to have relationship with Routine through the intermediate Progress

1 like

Please or to participate in this conversation.