eloquent - Laravel - Eager Loading Polymorphic Relation's Related Models -



eloquent - Laravel - Eager Loading Polymorphic Relation's Related Models -

i can eager load polymorphic relations/models without n+1 issues. however, if seek access model related polymorphic model, n+1 problem appears , can't seem find fix. here exact setup see locally:

1) db table name/data

history

companies

products

services

2) models

// history class history extends eloquent { protected $table = 'history'; public function historable(){ homecoming $this->morphto(); } } // company class company extends eloquent { protected $table = 'companies'; // each company has many products public function products() { homecoming $this->hasmany('product'); } // each company has many services public function services() { homecoming $this->hasmany('service'); } } // product class product extends eloquent { // each product belongs company public function company() { homecoming $this->belongsto('company'); } public function history() { homecoming $this->morphmany('history', 'historable'); } } // service class service extends eloquent { // each service belongs company public function company() { homecoming $this->belongsto('company'); } public function history() { homecoming $this->morphmany('history', 'historable'); } }

3) routing

route::get('/history', function(){ $histories = history::with('historable')->get(); homecoming view::make('historytemplate', compact('histories')); });

4) template n+1 logged becacuse of $history->historable->company->name, comment out, n+1 goes away.. need distant related company name:

@foreach($histories $history) <p> <u>{{ $history->historable->company->name }}</u> {{ $history->historable->name }}: {{ $history->historable->status }} </p> @endforeach {{ dd(db::getquerylog()); }}

i need able load company names eagerly (in single query) it's related model of polymorphic relation models product , service. i’ve been working on days can't find solution. history::with('historable.company')->get() ignores company in historable.company. efficient solution problem be?

solution:

it possible, if add:

class="lang-php prettyprint-override">protected $with = ['company'];

to both service , product models. way, company relation eager-loaded every time service or product loaded, including when loaded via polymorphic relation history.

explanation:

this result in additional 2 queries, 1 service , 1 product, i.e. 1 query each historable_type. total number of queries—regardless of number of results n—goes m+1 (without eager-loading distant company relation) (m*2)+1, m number of models linked polymorphic relation.

optional:

the downside of approach always eager-load company relation on service , product models. may or may not issue, depending on nature of data. if problem, utilize trick automatically eager-load company only when calling polymorphic relation.

add history model:

class="lang-php prettyprint-override">public function gethistorabletypeattribute($value) { if (is_null($value)) homecoming ($value); homecoming ($value.'withcompany'); }

now, when load historable polymorphic relation, eloquent classes servicewithcompany , productwithcompany, rather service or product. then, create classes, , set with within them:

productwithcompany.php

class="lang-php prettyprint-override">class productwithcompany extends product { protected $table = 'products'; protected $with = ['company']; }

servicewithcompany.php

class="lang-php prettyprint-override">class servicewithcompany extends service { protected $table = 'services'; protected $with = ['company']; }

...and finally, can remove protected $with = ['company']; base of operations service , product classes.

a bit hacky, should work.

laravel eloquent polymorphic-associations eager-loading polymorphism

Comments

Popular posts from this blog

Delphi change the assembly code of a running process -

json - Hibernate and Jackson (java.lang.IllegalStateException: Cannot call sendError() after the response has been committed) -

C++ 11 "class" keyword -