Я создавал приложение среднего размера и теперь разрешаю множество дополнительных вариантов использования.Это означает больше полагаться на события и слушателей и многократно касаться объектов в одном запросе.
В ходе этого процесса было несколько случаев, когда я был удивлен поведением отношений 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 (а не саму модель), это дало мне эффект, который я искал, достаточно элегантно.