Reputation: 15812
I have the following models set up in Laravel 5 (everything is namespaced into App\Models
, but I've removed that for readability) :
class Client extends Model {
public function templates() { return $this->hasMany('Template'); }
public function documents() { return $this->hasManyThrough('Template', 'Document'); }
public function users() { return $this->hasMany('User'); }
}
class Template extends Model {
public function client() { return $this->belongsTo('Client'); }
public function documents() { return $this->hasMany('Document'); }
}
class Document extends Model {
public function template() { return $this->belongsTo('Template'); }
}
In a controller, I have the current user:
$user = \Auth::user();
$client = $user->client;
I want to show a list of
It seems easy enough; I already have both of the relations needed. The question is, if I lazy eager load templates
and documents
onto $client
, do I still need to eager load templates.documents
(hasManyThrough) or is Laravel smart enough to realise?
$client->load( 'templates', 'documents' );
// or...
$client->load( 'templates', 'templates.documents' );
// or...
$client->load( 'templates', 'documents', 'templates.documents' );
Upvotes: 1
Views: 1401
Reputation: 15812
I've just found that it's possible to see if a relation is loaded, so I've run artisan tinker
and tested:
$c = Client::first();
array_key_exists('documents', $c->getRelations()); // false
// Loading `templates` and `documents` separately doesn't load `templates.documents`
$c = Client::first();
$c->load('templates', 'documents');
array_key_exists('documents', $c->getRelations()); // true
array_key_exists('documents', $c->templates->first()->getRelations()); // false
// Loading `documents.templates` doesn't load `documents` or `templates`
$c = Client::first();
$c->load('templates.documents');
array_key_exists('documents', $c->templates->first()->getRelations()); // true
array_key_exists('documents', $c->getRelations()); // false
So I guess the definitive answer is that if you have a hasManyThrough
you must explicitly load any relation you'll access - it's not smart enough to realise that it's already loaded the relation for you.
Upvotes: 0
Reputation: 1216
$client->load( 'templates', 'documents' );
Should be fine. hasManyThrough
is just a shortcut - laravel will try to get documents
from client
.
You can always check it yourself - run both, and compare results.
Upvotes: 0