ぞえの技術めも

Ruby on Rails勉強中

【46日目】【1日20分のRailsチュートリアル】【第6章】ユーザーのメールアドレスの一意性を検証する

Ruby on Railsチュートリアル(第3版)

今日は「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 一意性を検証する」のデータベースの話から。