【46日目】【1日20分のRailsチュートリアル】【第6章】ユーザーのメールアドレスの一意性を検証する
今日は「6.2.5 一意性を検証する」から。
6.2.5 一意性を検証する
メールアドレスの一意性を強制するために (ユーザー名として使うために)、validatesメソッドの:uniqueオプションを使います。
ふむふむ。
一意性のテストのためには、メモリ上だけではなく、実際にレコードをデータベースに登録する必要があります。
メモリ上だけじゃ駄目なのか。。。
複製したユーザーの有効性をチェックするテストを追加。
test/models/user_test.rb
test "email addresses should be unique" do duplicate_user = @user.dup @user.save assert_not duplicate_user.valid? end
duplicate_user.saveを実行したとき(=データベースに登録したとき)じゃなくて
メモリ上にレコード作ったときに有効性判定できるんだ。。
テスト実行。
$ bundle exec rake test:models 8 tests, 16 assertions, 1 failures, 0 errors, 0 skips
失敗する。
emailのバリデーションに一意性に関するオプションを追加。
app/models/user.rb
validates :email, presence: true, length: { maximum: 255 }, format: { with: VALID_EMAIL_REGEX }, uniqueness: true
テスト再実行。
$ bundle exec rake test:models 8 tests, 16 assertions, 0 failures, 0 errors, 0 skips
問題なし。
通常、メールアドレスでは大文字小文字が区別されません。
すなわち、foo@bar.comはFOO@BAR.COMやFoO@BAr.coMと書いても扱いは同じです。従って、メールアドレスの検証ではこのような場合も考慮する必要があります。
デフォルトでは大文字小文字が区別されてる、ってことか。
さっき追加したテストにて、
全て大文字に変換したメールアドレスを複製ユーザーに設定しておく。
test/models/user_test.rb
test "email addresses should be unique" do duplicate_user = @user.dup duplicate_user.email = @user.email.upcase @user.save assert_not duplicate_user.valid? end
テスト実行。
$ bundle exec rake test:models 8 tests, 16 assertions, 1 failures, 0 errors, 0 skips
失敗する。
さっき追加した:uniqueness
に大文字小文字を区別しないようなオプションを追加。
app/models/user.rb
validates :email, presence: true, length: { maximum: 255 }, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false }
テスト再実行。
$ bundle exec rake test:models 8 tests, 16 assertions, 0 failures, 0 errors, 0 skips
問題なし。
しかし、依然としてここには1つの問題が残っています。それはActive Recordはデータベースのレベルでは一意性を保証していないという問題です。
これ気になってた。
上のシナリオが信じがたいもののように思えるかもしれませんが、どうか信じてください。
www まぁ可能性は0です!とは言えないよね。
ここからがちょっと長いので今日はここまで。
今日の作業時間は【19分】。
次は「6.2.5 一意性を検証する」のデータベースの話から。