$mixtesttest/tv_recipe/users_test.exs.1) test username should be unique (TvRecipe.UserTest)test/tv_recipe/users_test.exs:24Assertionwithinfailedcode:%{username: ["用户名已被人占用"]} = errors_on(changeset)left:%{username: ["用户名已被人占用"]}right: [username: "has already been taken"]stacktrace:test/tv_recipe/users_test.exs:33: (test)..Finishedin0.1seconds4tests,1failure
diff --git a/test/tv_recipe/users_test.exs b/test/tv_recipe/users_test.exsindex 9748671..44cb21b 100644--- a/test/tv_recipe/users_test.exs+++ b/test/tv_recipe/users_test.exs@@ -32,4+32,13 @@ defmoduleTvRecipe.UserTestdo# 错误信息为“用户名已被人占用” assert %{username: ["用户名已被人占用"]} =errors_on(changeset)end++ test "username should be case insensitive"do+ user_changeset =User.changeset(%User{}, @valid_attrs)+TvRecipe.Repo.insert! user_changeset++# 尝试插入大小写不一致的用户名,应报告错误+ another_user_changeset =User.changeset(%User{}, %{@valid_attrs | username: "Chenxsan", email: "chenxsan+1@gmail.com"})+ assert {:error, changeset} =TvRecipe.Repo.insert(another_user_changeset)+endend
运行测试的结果是:
$mixtesttest/tv_recipe/users_test.exswarning:variable"changeset"isunusedtest/tv_recipe/users_test.exs:42...1) test username should be case insensitive (TvRecipe.UserTest)test/tv_recipe/users_test.exs:36match (=) failedcode:{:error,changeset}=TvRecipe.Repo.insert(another_user_changeset)right:{:ok,%TvRecipe.User{__meta__:#Ecto.Schema.Metadata<:loaded, "users">,email:"chenxsan+1@gmail.com",id:36,inserted_at:~N[2017-01-2411:57:43.741097],password:"some content",updated_at:~N[2017-01-2411:57:43.741109],username:"Chenxsan"}}stacktrace:test/tv_recipe/users_test.exs:42: (test).Finishedin0.1seconds5tests,1failure
Unfortunately, different databases provide different guarantees when it comes to case-sensitiveness. For example, in MySQL, comparisons are case-insensitive by default. In Postgres, users can define case insensitive column by using the :citext type/extension.
不同数据库对大小写的处理不一样,比如 MySQL 是大小写不敏感的,而默认情况下,PostgreSQL 字段是大小写敏感的,不过我们可以使用 citext 扩展类型。
如果不用 citext,文档中仍有其它办法:
If for some reason your database does not support case insensitive columns, you can explicitly downcase values before inserting/updating them
$mixecto.migrate20:39:44.900 [info] == Running TvRecipe.Repo.Migrations.AlterUserUsernameIndex.change/0 forward20:39:44.900 [info] drop index users_username_index20:39:44.930 [info] create index users_lower_username_index20:39:44.940 [info] == Migrated in 0.0s
mixtesttest/tv_recipe/users_test.exswarning:variable"changeset"isunusedtest/tv_recipe/users_test.exs:42.1) test username should be case insensitive (TvRecipe.UserTest)test/tv_recipe/users_test.exs:36** (Ecto.ConstraintError) constraint error when attempting to insert struct:*unique:users_lower_username_indexIfyouwouldliketoconvertthisconstraintintoanerror,pleasecallunique_constraint/3inyourchangesetanddefinetheproperconstraintname.Thechangesetdefinedthefollowingconstraints:*unique:users_email_index*unique:users_username_indexstacktrace: (ecto) lib/ecto/repo/schema.ex:493:anonymousfn/4inEcto.Repo.Schema.constraints_to_errors/3 (elixir) lib/enum.ex:1229:Enum."-map/2-lists^map/1-0-"/2 (ecto) lib/ecto/repo/schema.ex:479:Ecto.Repo.Schema.constraints_to_errors/3 (ecto) lib/ecto/repo/schema.ex:213:anonymousfn/13inEcto.Repo.Schema.do_insert/4test/tv_recipe/users_test.exs:42: (test).2) test username should be unique (TvRecipe.UserTest)test/tv_recipe/users_test.exs:24** (Ecto.ConstraintError) constraint error when attempting to insert struct:*unique:users_lower_username_indexIfyouwouldliketoconvertthisconstraintintoanerror,pleasecallunique_constraint/3inyourchangesetanddefinetheproperconstraintname.Thechangesetdefinedthefollowingconstraints:*unique:users_email_index*unique:users_username_indexstacktrace: (ecto) lib/ecto/repo/schema.ex:493:anonymousfn/4inEcto.Repo.Schema.constraints_to_errors/3 (elixir) lib/enum.ex:1229:Enum."-map/2-lists^map/1-0-"/2 (ecto) lib/ecto/repo/schema.ex:479:Ecto.Repo.Schema.constraints_to_errors/3 (ecto) lib/ecto/repo/schema.ex:213:anonymousfn/13inEcto.Repo.Schema.do_insert/4test/tv_recipe/users_test.exs:30: (test).Finishedin0.1seconds5tests,2failures