Laravel Basic принадлежит ToMany

У меня есть 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']) почти во всех моих случаях, особенно с соединениями, и вместо этого я вынуждаю меня использовать БД!

Как мы можем это исправить?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
1
0
55
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

код, кажется, работает, существует потенциальная проблема в определении метода 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();

Другие вопросы по теме