【发布时间】:2018-06-02 09:35:55
【问题描述】:
我一直在构建一个中型应用程序,现在正在启用许多辅助用例。这意味着更多地依赖事件和侦听器,并在单个请求中多次触摸对象。
在这个过程中,有几个案例让我对 Eloquent 关系的行为感到惊讶。显然,当我收到一个对象作为事件处理程序的参数时,我可能不知道它的详细历史记录,因此我需要了解何时/如何依赖它(以及何时/如何不依赖它)。
以我有一个父实体和许多子实体为例。这是父级的 Eloquent 关系:
public function children()
{
return $this->hasMany(Model\Child::class);
}
在父级的其他地方,我有一种添加子级的方法,如下所示:
public function addChildren(array $data)
{
$children = [];
foreach ($data as $child) {
$children[] = new Child($child);
}
$this->children()->saveMany($children);
}
在请求周期的后期,我正在测试父级的一些条件,如果是真的,我让子级使用$parent->children,并与他们做一些进一步的工作。
在有人指出我错过了一条业务规则之前,这一直很好——如果父母已经有了孩子,你就不能以这种方式添加孩子。为了处理这个问题,我在addChildren()方法的顶部做了一个简单的测试:
public function addChildren(array $data)
{
if(count($this->children)) {
throw new \Exception('Can not add children where they already exist');
}
// remainder of the method goes here...
}
当我添加此代码时,我开始得到意想不到的结果。经过调查,我发现通过在方法的早期计算孩子(显然意识到了这种关系),它会影响这种关系以后的表现。
我尝试在方法运行后转储$parent->children 的值。如果我排除首先计算孩子的代码,我会得到我所期望的 - 我新添加的孩子的集合。但是,如果我包含计数代码,我会得到一个空数组。
所以,问题是:
- 我是否使用了错误的关系?
- 我是不是对这种关系期望过高?
- 如果我不知道当前请求上下文中对象的历史记录,是否应该始终取消设置并重新加载关系?
- 我是否需要更深入地了解 Eloquent 才能对更复杂的用例充满信心?
- 是否有一些简单的规则可以帮助我掌握它?
- 还有什么...?
我非常喜欢 Laravel,所以很想了解这个亟待解决的问题......
编辑:
对于正在阅读这篇文章的任何人,我最终都会对用例的一些非核心部分进行排队。这对性能来说是一个很好的举措,并且在解耦方面感觉很好。因为 Laravel 序列化了 Eloquent 模型 id(而不是模型本身),它以一种相当优雅的方式给了我想要的效果。
【问题讨论】:
-
您可以在检查过程中尝试刷新
$this实例。$this->fresh('children'),或者更好的是检查$this->has('children')->get()或$this->children()->exists()- 它对数据库执行查询。 -
fresh返回一个新实例 ...load加载关系 ...refresh刷新当前实例