Ecto unique_constraint无法按预期工作

问题描述 投票:1回答:1

我想创建一个包含3个字段的unique_constraint,并将其命名为“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=12&s_id=12&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导致我的db在控制台中抛出红色错误?

elixir ecto
1个回答
7
投票

Ecto.Changeset.unique_constraint/3必须得到real unique constraint in the database的支持。以下是文档的摘录:

要使用唯一性约束,第一步是在迁移中定义唯一索引:

create unique_index(:users, [:email])

Ecto.Changeset.unique_constraint/3是为了模式匹配现有的唯一约束而构建的,这就是为什么如果数据库中没有这样的约束,就会引发FunctionClauseError

© www.soinside.com 2019 - 2024. All rights reserved.