阻止ecto抛出唯一约束错误

时间:2019-02-17 01:33:28

标签: elixir ecto

我一直收到此错误。该错误是预料之中的,但是如何处理这种情况,以免在控制台中引发红色文本?

代码:

  def insert_user_product(conn, user_product) do
    changeset = Api.UserProduct.changeset(%Api.UserProduct{}, user_product)
    errors = changeset.errors
    valid = changeset.valid?
    case insert(changeset) do
      {:ok, user_product} ->
        {:ok, user_product}
      {:error, changeset} ->
        {:error, :failure}
    end
  end

错误:

14:23:18.273 [error] #PID<0.354.0> running Api.Router terminated
Server: 172.20.10.6:4000 (http)
Request: PUT /product/isvegan/?p_id=1&u_id=792200324272726
** (exit) an exception was raised:
    ** (Ecto.ConstraintError) constraint error when attempting to insert struct:

    * unique: unique_user_product

If you would like to convert this constraint into an error, please
call unique_constraint/3 in your changeset and define the proper
constraint name. The changeset defined the following constraints:

    * unique: user_products_p_id_index

        (ecto) lib/ecto/repo/schema.ex:574: anonymous fn/4 in Ecto.Repo.Schema.constraints_to_errors/3
        (elixir) lib/enum.ex:1294: Enum."-map/2-lists^map/1-0-"/2
        (ecto) lib/ecto/repo/schema.ex:559: Ecto.Repo.Schema.constraints_to_errors/3
        (ecto) lib/ecto/repo/schema.ex:222: anonymous fn/14 in Ecto.Repo.Schema.do_insert/4
        (api) lib/api/models/user_product.ex:38: Api.UserProduct.insert_user_product/2
        (api) lib/api/controllers/product/put_product_is_vegan.ex:29: Api.Controllers.PutProductIsVegan.put_product_is_vegan/1
        (api) lib/api/router.ex:1: Api.Router.plug_builder_call/2
        (api) lib/plug/debugger.ex:123: Api.Router.call/2

1 个答案:

答案 0 :(得分:2)

就像错误消息一样,您需要在changeset函数中定义一个unique_constraint/3,以便ecto可以在DB抛出该错误之前捕获该错误。

defmodule Api.UserProduct do

....

  def changeset(struct, attrs) do
    struct
    |>cast(attrs, [...])
    |>validate_required([...])
    # Add this line
    |>unique_constraint(:p_id, message: "User product id already exists")
  end


end