【发布时间】:2015-04-14 18:02:21
【问题描述】:
我有一种情况,我需要遍历模型关系(一对多)并在孩子身上调用一个函数。即
$parent = ParentClass::find(1)
$children = $parent->children;
foreach($children as $child)
{
$child->function();
}
子内部的函数需要访问父模型的字段。即
public function function()
{
if($this->parent->attribute)
return "True!";
return "False";
}
按上述方式执行,最终会出现 N+1 查询问题。每个孩子最终都会执行“SELECT * FROM parents WHERE id = 1”。
我对如何解决这个问题有 3 个想法,虽然其中两个感觉很糟糕,最后一个对我来说似乎不太好,所以我想问有没有比我更好的解决方案考虑过吗?
解决方案 1:急切地将父模型加载到子模型中。即
...
$children = $parent->children;
$children->load('parent');
foreach($children as $child)
...
我认为这很明显为什么会很糟糕,将父模型存储在内存中 N+1 次将是一个巨大的内存消耗。
解决方案 2:将父级作为参数传递给子级,即
...
foreach($children as $child)
{
$child->function($parent);
}
...
避免了1的内存问题,但还是觉得难看。我认为孩子应该知道它是父母,而不需要通过方法 args 告诉它。
解决方案 3:将 remember() 添加到孩子的父关系中,即
public function parent()
{
return $this->hasOne('Parent')->remember(1);
}
由于所有的孩子都有相同的父母,这将缓存查询,并避免为每个孩子调用它。这似乎是这 3 种解决方案中最好的,但我不喜欢让这成为关系中的强制性内容。
有没有更好的方法我没有考虑?也许一个更好的地方包含记忆功能?
谢谢你,-沃利
【问题讨论】:
标签: php laravel-4 eloquent eager-loading