【问题标题】:Phoenix unique_constraint error while trying to build databasePhoenix 尝试构建数据库时出现 unique_constraint 错误
【发布时间】:2019-03-08 13:51:59
【问题描述】:

我正在关注 Phoenix 1.4 的书,当我尝试通过终端将数据放入数据库时​​,我进入了“使用存储库数据”部分,但出现错误。

我的 IEx 会话:

iex(1)> alias Rumbl.Repo
Rumbl.Repo
iex(2)> alias Rumbl.Accounts.User
Rumbl.Accounts.User
iex(3)> Repo.insert(%User{
...(3)> name: "José", username: "josevalim"
...(3)> })
[debug] QUERY ERROR db=16.7ms queue=1.2ms
INSERT INTO "users" ("name","username","inserted_at","updated_at") VALUES ($1,$2,$3,$4) RETURNING "id" ["José", "josevalim", ~N[2018-11-24 11:47:30], ~N[2018-11-24 11:47:30]]

它抛出了以下错误:

** (Ecto.ConstraintError) constraint error when attempting to insert struct:

    * users_username_index (unique_constraint)

If you would like to stop this constraint violation from raising an
exception and instead add it as an error to your changeset, please
call `unique_constraint/3` on your changeset with the constraint
`:name` as an option.

The changeset has not defined any constraint.

    (ecto) lib/ecto/repo/schema.ex:641: anonymous fn/4 in Ecto.Repo.Schema.constraints_to_errors/3
    (elixir) lib/enum.ex:1314: Enum."-map/2-lists^map/1-0-"/2
    (ecto) lib/ecto/repo/schema.ex:626: Ecto.Repo.Schema.constraints_to_errors/3
    (ecto) lib/ecto/repo/schema.ex:238: anonymous fn/15 in Ecto.Repo.Schema.do_insert/3

【问题讨论】:

  • 该错误表明您在数据库中已有具有该名称和用户名的行。当你运行Repo.all(User)Repo.get_by(User, name: "José", username: "josevalim")时你会得到什么

标签: elixir phoenix-framework ecto


【解决方案1】:

您的users表迁移中似乎创建了unique index

约束在您的username 键上,这意味着users 表中的两条记录不能具有相同的用户名。在您的情况下,这意味着您已经在表中创建了另一个用户名为 josevalim 的用户。


要让 Ecto 返回 {:error, changeset} 元组而不是引发错误,您可以告诉架构在您的 changeset/2 方法中有一个 unique constraint

def changeset(user, params) do
  user
  |> cast(params, [:name, :username])
  |> validate_required([:name, :username])
  |> unique_constraint(:username, name: :users_username_index)
end

并在插入任何内容之前使用此方法构建变更集:

%User{}
|> changeset(%{name: "José", username: "josevalim"})
|> Repo.insert

【讨论】:

  • 我想补充一点,:name 选项必须与 Ecto 生成的索引的名称匹配。
猜你喜欢
  • 2016-11-21
  • 1970-01-01
  • 2012-03-01
  • 2021-03-05
  • 2021-03-29
  • 1970-01-01
  • 2019-02-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多