laraveleloquentrelationshipeager-loading

Laravel morph child relationship eager loading


We have a few tables related as such:

Then we have various tables which contain meta data about the mission, depending on its type:

And finally some other tables which can be related to some modalities (but not all)

And here is our issue

We have a dashboard which lists all missions and displays some important information about them. Query looks like that:

Mission::with(['modality'])->get()

This is all good. But if we need to show information from a table related to the modality, we start getting N+1 queries.

We cannot go like that:

Mission::with([
   'modality',
   'modality.company',
   'modality.fiscal_year',
])->get()

Because some modality classes do not have the fiscal_year relationship and this results in an exception being thrown.

How could we get eager loading when relationship exists?


Solution

  • you can specify what relations to load based on the type of morph parent

    docs: https://laravel.com/docs/11.x/eloquent-relationships#nested-eager-loading-morphto-relationships

    Mission::query()
      ->with(['modality' => function (MorphTo $morphTo) {
            $morphTo->morphWith([
                AnnualStatementModality::class => ['company', 'fiscal_year'],
                NewCompanyModality::class => ['fiscal_year'],
                /** other cases as needed */
            ]);
        }])