Как получить прочные красноречивые отношения? - PullRequest
0 голосов
/ 01 июня 2018

Я создавал приложение среднего размера и теперь разрешаю множество дополнительных вариантов использования.Это означает больше полагаться на события и слушателей и многократно касаться объектов в одном запросе.

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

1 Ответ

0 голосов
/ 01 июня 2018

Нет, вы не используете отношения неправильно и не ожидаете слишком многого.

С идеей REST большую часть времени вам действительно не следует оказываться в ситуации, когда вы хотите загрузить отношения, добавить их, а затем вернуть новые отношения.Если у вас есть магазин или обновленный маршрут, вам не нужно загружать отношения заранее (если у вас нет конкретного варианта использования), а в остальное время вы просто должны вызывать отношения и возвращать результаты.

Если по какой-либо причине вам нужно изменить отношение (я уверен, что есть множество причин), а затем вернуть результаты, вы всегда можете просто перезагрузить отношение, например

$parent->fresh('children');

В качестве альтернативы, если вы просто хотите подсчитать детей, вы можете использовать запрос подсчета вместо получения всех children:

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

Это не будет загружать отношения, но даст вам знать, сколькоу вас есть дети.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...