donglinli2027 2015-04-21 12:17
浏览 126
已采纳

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

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

  • the templates for a client
  • the documents for a client, separately, not grouped by template

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' );
  • 写回答

2条回答 默认 最新

  • drap5081683 2015-04-21 12:59
    关注

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 求快手直播间榜单匿名采集ID用户名简单能学会的
  • ¥15 DS18B20内部ADC模数转换器
  • ¥15 做个有关计算的小程序
  • ¥15 MPI读取tif文件无法正常给各进程分配路径
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下
  • ¥15 setInterval 页面闪烁,怎么解决
  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历