【问题标题】:eager loading deeply nested relationships?急切地加载深度嵌套的关系?
【发布时间】:2014-01-26 23:19:27
【问题描述】:

我有一系列相关的表格;

trainers -> hasMany -> programs
programs -> hasMany -> weeks
weeks -> hasMany -> days
days -> hasMany -> sessions
sessions -> hasMany -> phases
phases -> hasMany -> excersises

相反方向的关系都有一个接受到阶段的练习,这也是 hasMany 和一个数据透视表

按照文档这样深入地建立关系显然可以正常工作

$programs = $this->program->orderBy('trainerId', 'asc')->take(1)->with('weeks.days')->get();

我需要能够检索整个程序的内容,并且我认为我可以像这样急切地加载每个嵌套关系

$programs = $this->program->orderBy('trainerId', 'asc')->take(1)->with('weeks.days', 'weeks.days.sessions')->get();

$programs = $this->program->orderBy('trainerId', 'asc')->take(1)->with('weeks.days.sessions')->get();

但两者都返回 FatalErrorException

调用未定义的方法 Illuminate\Support\Facades\Session::newQuery()

这样做的正确方法是什么?

【问题讨论】:

    标签: php mysql database laravel-4 eloquent


    【解决方案1】:

    从您的问题中,我可以看到您有如下嵌套关系。

    programs -> hasMany -> weeks
    -----------------------------weeks -> hasMany -> days
    ----------------------------------------------------days -> hasMany -> sessions
    

    如果我们不知道weeks,就很难知道应该为days 加载哪些数据。 sessions 也是如此。所以,我们必须先加载weeks数据,然后是days,然后是sessions

    从 Laravel 文档中,我们可以看到,Eager loading 使用以下方法:

    select * from books
    
    select * from authors where id in (1, 2, 3, 4, 5, ...)
    

    Laravel 根据books 数据加载author 数据。

    http://laravel.com/docs/eloquent#eager-loading

    先尝试加载weeks

    $programs = $this->program->orderBy('trainerId', 'asc')
       ->take(1)
       ->with('weeks', 'weeks.days', 'weeks.days.sessions')
       ->get();
    

    或:

    延迟加载:

     $programs = $this->program->orderBy('trainerId', 'asc')->take(1)->get();
    
     $programs->load('weeks', 'weeks.days', 'weeks.days.sessions');
    

    【讨论】:

    • 由于这与标题相关,因此我会将其标记为已接受,但如果有人遇到与我相同的错误,请在下面查看我的答案
    【解决方案2】:

    所以我发现了问题,它可能会帮助其他人知道答案。这个帖子给了我一个瞬间laravel forums

    我有一个名为 Session 的模型,laravel 在框架的其他地方使用该名称,呃,所以当它尝试调用我的模型时,它实际上是从框架深处的某个地方调用另一个会话类。我发现的一些解决方案建议使用命名空间,但我认为这对我不起作用,因为关系声明只是将带有类名的字符串传递给框架。我认为这意味着该类的调用发生在其他地方,如果我错了,我需要将命名空间 /use 放在那里纠正我。

    将会话类更改为 Sessionss 并更改关系以适应任何一种方式都解决了我的问题。

    我希望这可以帮助其他人不要浪费 36 个小时来解决这个问题:p

    【讨论】:

    • 命名空间将起作用。即使你提供了一个字符串,Laravel 也会尊重关系中的命名空间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-28
    • 2015-08-16
    • 1970-01-01
    • 2017-09-30
    相关资源
    最近更新 更多