Size: a a a

2020 September 07

МВ

Михаил Варнавский... in pro.elixir
Хз, если не понятно написал - могу уточнить что нужно ))))
источник

B

Bogdan in pro.elixir
Михаил Варнавский
Всем привет. Подскажите пожалуйста, как правильно обновить запись в БД вместе со связанными данными? У меня есть таблица
Product
,  она связана с таблицей
AttributeValues
как has_many. Я пытаюсь использовать Ecto.Schema, где полностью подготоваливаю всю структуру, используя
cast_assoc
. Insert работает как нужно, но не могу понять, как правильно сделать update? Нужно сначала удалить связанные данные? Гуглил про
put_assoc
, но что-то не догнал, когда именно его нужно использовать (вроде только при обновлении связанных данных)
либо функция Repo.update/update_all, либо upsert-ы
источник

B

Bogdan in pro.elixir
Удалять ничего не надо, чтобы обновлять данные.
источник

B

Bogdan in pro.elixir
я кстати нашел для себя более простым и гибким способом, не использовать абстрации cast_assoc и put_assoc, а обходится без них явно проставляя ключи.
источник

МВ

Михаил Варнавский... in pro.elixir
ну тут может быть такая ситуация, что перечень значений атрибутов изменился, например их стало меньше или совсем другой состав. Поэтому и подумал, что связанные данные проще полностью удалить и записать по-новой
источник

B

Bogdan in pro.elixir
Михаил Варнавский
ну тут может быть такая ситуация, что перечень значений атрибутов изменился, например их стало меньше или совсем другой состав. Поэтому и подумал, что связанные данные проще полностью удалить и записать по-новой
Если так изменились данные, что их нужно удалить - это Repo.delete/delete_all коллбеки.
источник

B

Bogdan in pro.elixir
А для апдейта Repo.update/update_all или upsert-ы. Я бы не пускал delete операции вместе с апдейтами.
источник

B

Bogdan in pro.elixir
Михаил Варнавский
ну тут может быть такая ситуация, что перечень значений атрибутов изменился, например их стало меньше или совсем другой состав. Поэтому и подумал, что связанные данные проще полностью удалить и записать по-новой
Просто удалить и записать это две транзакции в БД.
источник

B

Bogdan in pro.elixir
к тому же.
источник

МВ

Михаил Варнавский... in pro.elixir
Bogdan
А для апдейта Repo.update/update_all или upsert-ы. Я бы не пускал delete операции вместе с апдейтами.
а какой вариант тогда возможен? На вход подается мапа с измененным объектом, который включает в себя и зависимости. Состав зависимостей может отличаться кардинально
источник

МВ

Михаил Варнавский... in pro.elixir
я пытался вот так:
    changeset = create_changeset(params)
   del_query = from(value in AttributeValue, where: value.product_id == ^params.product_id)

   Multi.new()
   |> Multi.delete_all(:delete_attributes_values, del_query)
   |> Multi.update(:update_product, changeset)
   |> Repo.transaction()
источник

МВ

Михаил Варнавский... in pro.elixir
но появляется ошибка (Ecto.NoPrimaryKeyValueError), я так понимаю из-за того, что не указал перечень обновляемых полей...
источник

МВ

Михаил Варнавский... in pro.elixir
хотя нет, сейчас проверил, в changeset в поле changes все поля указаны
источник

B

Bogdan in pro.elixir
А зачем ты мульти здесь используешь?
источник

B

Bogdan in pro.elixir
и что ты хочешь в продукте обновить?
источник

B

Bogdan in pro.elixir
Если ты удалил все атрибуты, что должно произойти с продуктом?
источник

МВ

Михаил Варнавский... in pro.elixir
мульти использую, чтобы все это дело было в одной транзакции, так как продукт и значения атрибутов в данном случае - одно целое. Если где-то что-то пойдет не так, нужно откатить все изменения.
Что именно будет обновлено в продукте я заранее не знаю, может все поля, а может только одно, а также может быть изменен состав значений атрибутов, либо только значений
источник

МВ

Михаил Варнавский... in pro.elixir
считай, что это для API: мне прилетает измененный продукт и эти изменения нужно сохранить в базу. Что именно прилетит - неизвестно. Для внешнего пользователя это все одна структура, в состав которой входят значения атрибутов
источник

B

Bogdan in pro.elixir
Тогда все должно работать так как ты и ожидаешь этого.  По-поводу ошибки проверь схему миграции и тд все ли на месте с ключами.
источник

B

Bogdan in pro.elixir
Ecto.NoPrimaryKeyValueError exception
Raised at runtime when an operation that requires a primary key is invoked with a schema missing value for its primary key
источник