【问题标题】:Eloquent eager load constrain by parent column values雄辩的急切负载受父列值约束
【发布时间】:2016-05-26 04:12:48
【问题描述】:

我在 Laravel 5.2 上,我在使用 Eloquent 检索具有急切加载关系的数据时遇到问题,这些关系需要受到其他关系的值的约束。我不确定这种关系模式的正确术语,因此很难找到解决方案。

架构

为清楚起见,简化了代码和表格/模型:

三个表/模型

E、D 和 M.

关系

class D extends Model
{
  public function E()
  {
    return $this->belongsTo('App\E');
  }
}

class E extends Model
{
  public function D()
  {
    return $this->hasMany('App\D');
  }
  public function M()
  {
    return $this->hasMany('App\M');
  }
}

class M extends Model
{
  public function E()
  {
    return $this->belongsTo('App\E');
  }
}

架构示例D <*--1> E <1--*> M

D 和 M 之间没有直接关系。

问题

我想要一个 D 的列表,其中 E 和 M 急切地加载到 D 对象的属性中,这样 $D->E->M 是属于该 E 的 M 的列表,而该 E 又属于 D .

问题是我需要 M 的急切加载受到 D 上列的值的约束。

例子:

$D = \App\D::with(['E' => function($query) {

  $query->with(['M' => function($query) {

    //example of what I'd like to do (but doesn't work)
    $query->where('start_timestamp','>=','D.start_timestamp'); 

  }]);

}])->get();

在该示例中,它尝试将 M 的 start_timestamp 字段与字符串“D.start_timestamp”进行比较,而不是 D 的 start_timestamp 值。

问题

是否可以通过较早的相关列值来限制急切加载?如果有,怎么做?

我试过了……

...使用 $query->whereRaw 显式引用早期表的列

$query->whereRaw('M.start_timestamp >= D.start_timestamp')

但此错误将 'D.start_timestamp' 作为未知列。

...使用 whereColumn,但这似乎不适用于急切加载约束(未知列“列”出现错误)。


我试图以“雄辩的方式”解决这个问题,避免使用原始 SQL 和连接。我知道如何通过 SQL 和连接来解决这个问题,但如果可能的话,我宁愿避免它。

如果您能提供任何帮助,我们将不胜感激,谢谢。

【问题讨论】:

  • 您是否在请求的模型中创建了任何关系?如果是,请分享您的关系
  • 是的,我有,我编辑了问题以提供关系代码。
  • 这样的急切加载没有雄辩的方式。你可以使用whereHas,但很难从你的帖子中看出你真正需要什么。更好地显示您尝试运行的真实模型名称和代码与结果与预期结果。
  • 谢谢,我也很怀疑。我需要的内容列在“问题”下,我需要在执行引用其他表中的列的where 时急切加载。但是,从生成的 SQL 来看,这似乎是不可能的,因为急切加载查询似乎独立于第一个查询。

标签: laravel orm laravel-5 eloquent laravel-5.2


【解决方案1】:

您的上述问题陈述令人困惑,但据我了解,您希望从D 急切加载M 记录,即D -> E -> M 并且DM 之间没有直接关系。你可以这样做

例如:

D与E有关系

E与M有关系

如果你想加载所有相关的记录,你可以这样做

D::with(
     //this will fetch E records which belongs to D
     ['E'=>function($q){
         //your desire query, which you want to apply on E model/records
         $q->where('status','1')->where('problemname', '<>',null);

        },

     //this will fetch M records which belongs to E
     'E.M'=>function($q){
         //your desire query, which you want to apply on M model/records
         $q->where('status','1')->where('details', '<>',null);
        },
     ])->get();

您的结果将如下所示

父级将包含 D 条记录

Array(
   'name'=>'test',
   'email'=>'test@test.com',
   'dob'=>'1990-01-01',

   'E'=>Array(
         'problemname'=>'test',
         'problemtitle'=>'hello',
         'status'=>'1',
         ...

         'M'=>Array(
                'details'=>'test',
                'address'=>'hello',
                'status'=>'1',
                ...
              )
        )
)

【讨论】:

  • 对不起,不知道怎么说得更清楚,我是第一次问问题,很难用语言表达。是的,您的示例将起作用,而且我已经达到了这一点。我需要的是仅根据 D 中包含的值获取某些 M 记录。因此,例如,如果 D 记录有一个字段 status = 10,我可能想急切加载具有自己字段的 M 记录status 大于 D 记录的 status 字段 (10)。但似乎没有办法从急切加载 M 结果的查询中访问 D 查询的结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-29
  • 1970-01-01
  • 2013-09-22
  • 1970-01-01
  • 2020-02-26
  • 2019-12-24
相关资源
最近更新 更多