#elixir #ecto
#elixir #ecto
Вопрос:
Я хочу создать unique_constraint с 3 полями и назвать его «unique_user_product_shop». Когда я делаю это, моя база данных выдает сообщение об ошибке, в котором говорится, что попытка вставки не была уникальной:
ошибка:
18:04:18.830 [error] #PID<0.380.0> running Api.Router terminated
Server: 192.168.1.12:4000 (http)
Request: PUT /product/isinshop/?p_id=12amp;s_id=12amp;u_id=792200324272726
** (exit) an exception was raised:
** (FunctionClauseError) no function clause matching in Ecto.Changeset.add_constraint/6
(ecto) lib/ecto/changeset.ex:2272: Ecto.Changeset.add_constraint(#Ecto.Changeset<action: nil, changes: %{p_id: 12, s_id: 12, u_id: "792200324272726", voted_in_shop: true, voted_not_in_shop: false}, errors: [], data: #Api.UserProductShop<>, valid?: true>, :unique, "unique_user_product_shop", :exact, [:p_id, :u_id, :s_id], {"has already been taken", []})
(api) lib/api/models/user_product_shop.ex:37: Api.UserProductShop.insert_user_product_shop/2
(api) lib/api/controllers/product/put_product_is_in_shop.ex:48: Api.Controllers.PutProductIsInShop.put_product_is_in_shop/1
(api) lib/api/router.ex:1: Api.Router.plug_builder_call/2
(api) lib/plug/debugger.ex:123: Api.Router.call/2
(plug) lib/plug/adapters/cowboy/handler.ex:15: Plug.Adapters.Cowboy.Handler.upgrade/4
(cowboy) /Users/Ben/Development/Projects/vepo/api/deps/cowboy/src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4
мой код:
def changeset(user_product_shop, params \ %{}) do
user_product_shop
|> cast(params, [
:u_id,
:p_id,
:s_id,
:voted_not_in_shop,
:voted_in_shop])
|> validate_required([:u_id, :p_id, :s_id])
|> unique_constraint([:p_id, :u_id, :s_id], name: :unique_user_product_shop)
end
Итак, почему он не распознает мой unique_constraint, из-за чего моя база данных выдает красную ошибку в консоли?
Комментарии:
1. Ваш код взорван в вашей функции набора изменений. Это даже не попадает в базу данных. Я не верю, что это
unique_constraint
может принимать массив полей. Вы должны добавить ошибку в одно поле или в:base
. Документы: hexdocs.pm/ecto/Ecto. Набор изменений.html#unique_constraint/3
Ответ №1:
Ecto.Changeset.unique_constraint/3
необходимо создать резервную копию с помощью реального ограничения уникальности в базе данных. Вот выдержка из документации:
Чтобы использовать ограничение уникальности, первым шагом является определение уникального индекса при миграции:
create unique_index(:users, [:email])
Ecto.Changeset.unique_constraint/3
создается так, чтобы шаблон соответствовал только существующим уникальным ограничениям, поэтому, если в базе данных нет такого ограничения, FunctionClauseError
возникает.