如何获得坚如磐石的雄辩关系?

时间:2018-06-01 07:23:38

标签: laravel 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(而不是模型本身),它以合理优雅的方式给了我正在寻找的效果。

1 个答案:

答案 0 :(得分:2)

不,你没有以错误的方式使用关系,你也没有期待太多。

有了REST的想法,大部分时间你都不应该发现自己处于想要加载关系,添加关系然后返回新关系的情况。如果您有商店或更新路线,那么您不需要事先加载关系(除非您有特定用例),其余时间您应该只是调用关系并返回结果。

如果出于某种原因,你需要修改关系(我确定有很多理由),然后返回结果,你可以随时重新加载关系,例如。

$parent->fresh('children');

或者,如果您只想计算孩子的数量,则可以使用计数查询而不是获取所有children

$parent->children()->count();

这不会加载关系,但会告诉您有多少孩子。