Laravel拥有许多通过和懒惰的渴望加载

时间:2015-04-21 12:17:38

标签: php laravel laravel-5

我在Laravel 5中设置了以下模型(所有内容都被命名为App\Models,但为了便于阅读,我删除了它:)

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'); }
}

在控制器中,我有当前用户:

$user = \Auth::user();
$client = $user->client;

我想显示一个

列表
  • 客户端模板
  • 客户的文档,单独,不按模板分组

看起来很容易;我已经拥有了所需的两种关系。问题是,如果我懒得加载templatesdocuments$client,我还需要急切加载templates.documents(hasManyThrough)还是Laravel足够聪明才能实现?

$client->load( 'templates', 'documents' );
// or...
$client->load( 'templates', 'templates.documents' );
// or...
$client->load( 'templates', 'documents', 'templates.documents' );

2 个答案:

答案 0 :(得分:0)

$client->load( 'templates', 'documents' );

应该没问题。 hasManyThrough只是一个捷径 - laravel会尝试从documents获取client

您可以随时自行检查 - 同时运行并比较结果。

答案 1 :(得分:0)

我刚发现它是possible to see if a relation is loaded,所以我已经artisan tinker运行并经过测试:

$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

所以我想最明确的答案是,如果您有hasManyThrough必须明确加载您将要访问的任何关系 - 它不够智能,无法实现已经加载了你的关系。