访问 Parent 关系 Laravel

Accessing Parent relations Laravel

我有一种情况需要遍历模型关系(一对多)并调用 children 上的函数。即

$parent = ParentClass::find(1)
$children = $parent->children;
foreach($children as $child)
{
    $child->function();
}

child 中的函数需要访问 parent 模型中的字段。即

public function function()
{
    if($this->parent->attribute)
        return "True!";
    return "False";
}

如上执行此操作,最终出现 N+1 查询问题。每个 child 最终执行 "SELECT * FROM parents WHERE id = 1".

关于如何解决这个问题,我有 3 个想法,尽管其中两个感觉很糟糕,最后一个对我来说似乎不太好,所以我想问有没有比这个更好的解决方案我考虑了什么?

解决方案 1:急切地将 parent 加载到 child 模型上。即

...
$children = $parent->children;
$children->load('parent');
foreach($children as $child)
...

我认为很明显为什么这会很糟糕,将 parent 模型存储在内存中 N+1 次将是一个巨大的内存消耗。

解决方案 2:将 parent 作为参数传递给 child,即

...
foreach($children as $child)
{
    $child->function($parent);
}
...

避免了1的内存问题,但还是觉得丑。我认为 child 应该知道它是 parent,而不需要通过方法 args 告诉它。

解决方案 3:将 remember() 添加到 child 的 parent 关系中,即

public function parent()
{
    return $this->hasOne('Parent')->remember(1);
}

由于所有 children 都具有相同的 parent,这将缓存查询,并避免为每个 child 调用它。这似乎是这 3 种解决方案中最好的,但我不喜欢将其作为关系中强制性要求的想法。

有没有我没有考虑的更好的方法?也许是包含记忆功能的更好地方?

谢谢你,-Wally

如果您定义了反向关系,您可以执行以下操作:

$parent = ParentClass::find(1);
foreach ($parent->children as $child) {
    $requiredParentAttr = $parent->attr;
    $child->function($requiredParentAttr);
    // whatever else
}

我想我找到了一个令我满意的解决方案。我仍然感觉不到 "Eloquent",但我认为可能没有更好的解决方案,(尽管随时证明我错了。)

foreach($children as $child)
{
    $child->parent = $parent;
    $child->function();
}

既然我们已经有了父对象,就把父对象赋值给每个子对象作为引用。这避免了任何内存问题。这甚至比 remember() 选项更好,因为它从不为父级执行第二次查询。这使方法签名保持干净和合乎逻辑。