【问题标题】:How to use eager loading for related models in Laravel如何在 Laravel 中对相关模型使用预先加载
【发布时间】:2016-04-18 05:27:43
【问题描述】:

我有以下型号:

  • 约会 [ 属于时间段 |属于用户]
  • 时间段 [ hasMany Appointment ]​​i>
  • 用户 [ hasOne 约会 | HasOne 详情]
  • 详细信息 [ 属于用户]

我正在尝试使用以下查询从 Appointment 模型开始加载 Details 数据(Appointment 有一个用户,该用户有一个 Details 记录):

$apps = Appointment::with('timeslot')->with('user')->with('user.details')->get();

这会在 Builder.php 中引发以下错误

在非对象上调用成员函数 addEagerConstraints()

为什么我在这里调用一个非对象,为什么我的查询不起作用?

编辑:

这是我的用户模型上的关系:

public function details() {
    dd($this->role_id);
    switch($this->role_id) {
        case 3:
            return $this->hasOne('App\CandidateDetails', 'user_id');
            break;
        case 2:
            return $this->hasOne('App\EmployerDetails', 'user_id');
            break;
    }

}

我知道使用数据透视表会更好地实现这一点,这是一个学习过程。 dd() 在我的查询调用时返回 null,但在其他调用中工作正常。这里发生了什么?

【问题讨论】:

    标签: php laravel orm laravel-5 eloquent


    【解决方案1】:

    确保在所有关系方法中都有 return。似乎其中一个没有返回 Relation 定义。

    您不能在关系定义中使用 $this - 构建查询时模型的属性将未启动,因此 $this->role_id 将给出 null 并且不会返回任何关系。

    为了使其工作,您应该定义 2 个独立的关系:

    // User.php
    public function candidateDetails() {
      return $this->hasOne('App\CandidateDetails', 'user_id');
    }
    
    public function cemployerDetails() {
      return $this->hasOne('App\EmployerDetails', 'user_id');
    }
    
    public function getDetailsAttribute() {
      switch($this->role_id) {
        case 3:
          return $this->candidateDetails;
        case 2:
          return $this->employerDetails;
      }
    }
    
    // ...and then...
    $user = User::with('candidateDetails', 'employerDetails')->findOrFail($userId);
    // depending on user's role you'll get either candidate or employer details here
    $details = $user->details;
    

    【讨论】:

    • 您不能在关系定义中使用 $this - 构建查询时模型的属性将未启动,因此 $this->role_id 将给出 null 并且不会返回任何关系
    • 那么最优雅的实现方式是什么?我有一个在用户表上运行的用户模型。每条记录要么与候选人或雇主表有关系。
    • 我会定义 2 个独立的关系,急切地加载两者并定义一个 getter,对于给定的用户,它会根据角色返回任一相关字段。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-23
    • 2014-10-29
    • 1970-01-01
    • 2013-06-10
    • 2021-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多