Почему HasOneOrMany не обновляет отношения на родительском?

Мы разрабатываем корзину для электронной коммерции, используя Laravel 5.3, в которой есть предметы. Таким образом, наша корзина имеет отношение 1: n к товарам.

Когда мы добавляем продукт в корзину, используя Illuminate\Database\Eloquent\Relations\HasOneOrMany::save() это не подталкивает новый предмет к нашему $cart->items сбор, это должно быть сделано вручную с помощью Collection::push() метод.

Мы просим об этом, потому что Illuminate\Database\Eloquent\Relations\BelongsTo::associate() Метод делает это, поэтому мы не знаем, если это ошибка.

Просто для лучшего понимания:

Теперь нам нужно сделать это:

$cart = Cart::first();

$cartItem = new CartItem();
$cartItem->quantity = 1;
$cartItem->base_price = 1;
$cartItem->paid_price = 1;

$cart->items()->save($cartItem);
print($cart->items->count()); # returns 0
$cart->items->push($cartItem);
print($cart->items->count()); # returns 1

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

$cart = Cart::first();

$cartItem = new CartItem();
$cartItem->quantity = 1;
$cartItem->base_price = 1;
$cartItem->paid_price = 1;

$cart->items()->save($cartItem);
print($cart->items->count()); # returns 1

Мы думаем о том, чтобы сделать запрос на извлечение, потому что мы видели код, и это можно сделать. Но правильно ли это? Можем ли мы сделать это?

Дублируется отсюда: https://github.com/laravel/framework/issues/14719

Спасибо

1

Решение

Вы можете быть заинтересованы в обсуждении Эта проблема. Я скопировал комментарии, которые я сделал по этому вопросу здесь, на случай, если эта ссылка исчезнет в какой-то момент.

Информация о том, как загружаются атрибуты отношений:

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

// relationship attribute lazy loaded here
$blog->posts->count()

$post = new Post(['title' => 'post title');

// typo in OP; save() must be called on relationship method, not relationship attribute
$blog->posts()->save($post);

// relationship already loaded. Collection has not changed.
$blog->posts->count(); // 0

// however, call to database will reflect current count
$blog->posts()->count(); // 1

// reload the relationship attribute
$blog->load('posts');

// relationship collection refreshed; count of relationship attribute will reflect this
$blog->posts->count(); // 1

Почему атрибут отношения Collection не обновляется при добавлении элемента в отношение:

Я думаю, что слишком много неопределенности, чтобы попытаться изменить
Коллекция. Даже если вы связываете пост с блогом через
posts() отношения, нет никакой гарантии, что новый пост
должен быть загружен в атрибут отношения Collection в
первое место.

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

// only get posts created before today
public function posts() {
return $this->hasMany(Post::class)->where('created_at', '<', date('Y-m-d'));
}

Учитывая эти отношения, так как новый пост создается сегодня, он будет
быть неверным, если он был просто введен в существующий ленивый загруженный
$blog->posts сбор, потому что он не соответствует добавленной где
состояние. Если вы перезагрузите эти отношения, новый пост все равно
не быть в этом.

Другой пример будет следующим:

// get the posts, newest first
public function posts() {
return $this->hasMany(Post::class)->orderBy('created_at', 'DESC');
}

Учитывая это отношение, если новый пост добавляется в конец
существующие загружены $blog->posts коллекция, это будет в неправильном
порядок. Можно утверждать, что это можно добавить к началу, но
тогда это было бы в неправильном порядке, если бы отношения были
заказал ASC. Вы должны были бы проанализировать запрос отношения, чтобы попытаться
выяснить, где добавить элемент.

Теперь это просто простые примеры. Я уверен, что есть много очень
сложные отношения там, где было бы невозможно
проанализировать все ограничения и условия, чтобы правильно вставить
новый предмет в существующую коллекцию.

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

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]