У меня есть ProductCollection
Модель и AttributeValue
Модель, которые имеют общую таблицу product_collection_attributes
с двумя столбцами: product_collection_id
и attribute_value_id
, которые являются внешним ключом для соответствующих таблиц и оба являются первичными ключами.
В модели ProductCollection отношение:
public function attributes()
{
return $this->belongsToMany(AttributeValue::class, 'product_collection_attributes', 'product_collection_id');
}
И в отношении модели AttributeValue:
public function product_collections()
{
return $this->belongsToMany(ProductCollection::class, 'product_collection_attributes', 'attribute_value_id');
}
Мой запрос: $productCollection->attributes()->get()
; который возвращает пустой массив,
Однако если запрос был DB::table('product_collection_attributes')->where('product_collection_id', $productCollection->id)->get();
, он возвращает полный массив!
И САМОЕ ГЛАВНОЕ Это происходит только после следующего кода, КОТОРЫЙ ЛОМАЕТСЯ с ошибкой: (Exception: "SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2-2' for key 'product_collection_attributes.PRIMARY' (Connection: mysql, SQL: insert into
product_collection_attributes (
attribute_value_id,
product_collection_id) values (2, 2))"
): `
$productCollection->update([
SOMEINFO...,
'allow_price_change' => 0
]);
$data['attributes'] = [1,2];
$productCollection->attributes()->delete();
if (isset($data['attributes']) && count($data['attributes'])) {
$data['attributes'] = array_unique($data['attributes']);
$data['attributes'] = array_values(array_filter($data['attributes']));
$productCollection->attributes()->attach($data['attributes']);
}
ПОЭТОМУ Я ЗАМЕНИЛ ПРИВЕДЕННЫЙ КОД НА:
$productCollection->update([
SOMEINFO...,
'allow_price_change' => 0
]);
$data['attributes'] = [1,2];
DB::table('product_collection_attributes')->where('product_collection_id', $productCollection->id)->delete();
if (isset($data['attributes']) && count($data['attributes'])) {
$data['attributes'] = array_unique($data['attributes']);
$data['attributes'] = array_values(array_filter($data['attributes']));
$productCollection->attributes()->attach($data['attributes']);
}
И СЕЙЧАС у меня такая проблема, $productCollection->attributes()->get()
больше не работает!! и только DB::table('product_collection_attributes')->where('product_collection_id', $productCollection->id)->get();
работает!!
And note that if I update something in product collection that isn't a boolean all works fine!!, so update $productCollection->update(['name' => 'aaa', ...]) then update attributes will be fine
Я не знаю, почему, и важно использовать ProductCollection::with(['attributes'])
почти во всех моих случаях, особенно с соединениями, и вместо этого я вынуждаю меня использовать БД!
Как мы можем это исправить?
код, кажется, работает, существует потенциальная проблема в определении метода product_collections(). Он определен в модели AttributeValue, но назван так, будто предназначен для извлечения связанных коллекций ProductCollections. Если вы собираетесь получить связанные ProductCollections, вам следует определить связь в модели AttributeValue как productCollections() или что-то подобное.
public function productCollections()
{
return $this->belongsToMany(ProductCollection::class, 'product_collection_attributes', 'attribute_value_id');
}
Проблема заключалась в том, как я удалял $productCollection->attributes().
Правильный способ $productCollection->attributes()->detach();
А не ->delete().
Проблему было легко увидеть после обновления миграции. Что на самом деле произошло: запись AttributeValue была удалена!! и я использовал мягкое удаление, поэтому это было трудно заметить!!
Новая миграция показала это.
ТАК исправление: $productCollection->attributes()->detach();