#Eager load has many children

1 messages · Page 1 of 1 (latest)

digital cypress
#

Is it possible to eager load children that have children that also might have children etc...

class MaterialDetails extends Model
{
    public function children()
    {
        return $this->hasMany(MaterialDetails::class, 'parent_id');
    }

    public function parent()
    {
        return $this->belongsTo(MaterialDetails::class, 'parent_id');
    }
}

Is there any better way to do it:

  MaterialDetails::with('children.children.children.children.children.children.children.children.children');
sand yarrow
#

@digital cypress

If you put

protected $with = ['children'];

In MaterialDetails model

I think this will load all childrens but note that if you set this in model its mean when ever you get children relationship all the time and if you dont want
that be default loading so you can do this

MaterialDetails::setEggerLoads([])->get()

now this will not loads the relationships that are egger loaded in model

digital cypress
sand yarrow
#

@digital cypress welcome, and note again that relation will load every time you get your model what ever like in route model bindings or any where else that will load up and you can set setEggerLoads([]) to empty array to not loading the relations

#

@digital cypress what if you remove $with from your model and do MatarialDetails::setEggerLoads(['children'])->get(), this one is best I think if you want loads up childrens needed only in one place

#

so that you dont need to setEggerLoads to empty array in other places where you do not want that relations

#

try that I am not sure about that because I did not do that just it came to my mind

#

and let me know if this works

digital cypress
#

Actually I have Material model and I load it's relation (materialDetails)

Material::with('materialDetails');

Can I specify eager loading of relation (add children)?

sand yarrow
#

yes let my type

#

Material::with(['materialDetails' => fn ($materialDetails) => $materialDetails->setEggerLoads(['children'])])->get();

#

I hope this will work

#

and please keep eye on type mistakes when ever you use someone else code becuae I did not try this just type and send

digital cypress
#

Yeah, I got the gist of it.

Material::with(['materialDetails' => fn ($relation) => $relation->setEagerLoads(['children'])]);

This gives me an error
Illuminate\Database\Eloquent\Builder::eagerLoadRelation(): Argument #3 ($constraints) must be of type Closure, string given, called in ...\laravel\framework\src\Illuminate\Database\Eloquent\Builder.php on line 754

sage solar
#

Try with [$relation, 'children'] in setEagerLoads()

digital cypress
#

Got the same error with

Material::with(['materialDetails' => fn ($relation) => $relation->setEagerLoads([$relation, 'children'])]);
sand yarrow
#

In my case it says method not exist on

#

on HasMany relation ship

digital cypress
#

You have a typo there "setEggerLoads"

sand yarrow
#

ya I have catchup that

#

now see this there is only one argument 😂

#

and error says about the third argument

#

Oh

#

I got it

#

error is on this function 😂

#

@digital cypress I think you should go with the first approach I will see that latter on when have free time,

digital cypress
#

Yeah... I need to specify it in controller somehow.
Have you had time to look?