我跟着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
答案 0 :(得分: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