$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
$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