ぞえの技術めも

Ruby on Rails勉強中

【45日目】【1日20分のRailsチュートリアル】【第6章】ユーザー情報の文字列の長さとフォーマットを検証する

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

今日は「6.2.3 長さを検証する」から。

6.2.3 長さを検証する

最長のユーザー名の長さに科学的な根拠はありませんので、単に50を上限として手頃な値を使うことにします。

問題になる可能性もあるので長すぎるメールアドレスに対してもバリデーションを掛けましょう。ほとんどのデータベースでは文字列の上限を255としているので、それに合わせて255文字を上限とします。

というわけで文字列の長さをチェックするテストを追加。

test/models/user_test.rb

  test "name should not be too long" do
    @user.name = "a" * 51
    assert_not @user.valid?
  end

  test "email should not be too long" do
    @user.email = "a" * 244 + "@example.com"
    assert_not @user.valid?
  end

文字列の掛け算使うのか。なるほど~。(自分で文字数数えて定義、を考えてた)

テスト実行。
(チュートリアルのテスト実行コマンドが変わってるけどモデルに対してテスト実行でいいよね。。。)

$ bundle exec rake test:models
5 tests, 5 assertions, 2 failures, 0 errors, 0 skips

失敗します。

ユーザーモデルに長さの上限を追加。

app/models/user.rb

  validates :name, presence: true, length: { maximum: 50 }
  validates :email, presence: true, length: { maximum: 255 }

テスト再実行。

$ bundle exec rake test:models
5 tests, 5 assertions, 0 failures, 0 errors, 0 skips

問題なし。

6.2.4 フォーマットを検証する

メールアドレスのフォーマット(@の後の文字列に出てきていい記号は"."だけ、とか)をチェックするテストを追加する。
まずは有効なメールアドレスをチェックするテストを追加。

この辺って正規表現使えないのかな…色んなパターン考えるのめんどくさいよね。。。

test/models/user_test.rb

  test "email validation should accept valid addresses" do
    valid_addresses = %w[user@example.com USER@foo.COM A_US-ER@foo.bar.org
                         first.last@foo.jp alice+bob@baz.cn]
    valid_addresses.each do |valid_address|
      @user.email = valid_address
      assert @user.valid?, "#{valid_address.inspect} should be valid"
    end
  end

%w[]使えば文字列の配列がかんたんに作れるらしい。

次に有効じゃないメールアドレスをチェックするテストを追加。
@がなかったり@以降に"."以外の記号があったりするのはNG。

  test "email validation should reject invalid addresses" do
    invalid_addresses = %w[user@example,com user_at_foo.org user.name@example.
                           foo@bar_baz.com foo@bar+baz.com]
    invalid_addresses.each do |invalid_address|
      @user.email = invalid_address
      assert_not @user.valid?, "#{invalid_address.inspect} should be invalid"
    end
  end

テストは失敗します。

$ bundle exec rake test:models
   :
 FAIL["test_email_validation_should_reject_invalid_addresses", UserTest, 2016-08-09 12:46:01 +0000]
 test_email_validation_should_reject_invalid_addresses#UserTest (1470746761.12s)
        "user@example,com" should be invalid
   :
7 tests, 11 assertions, 1 failures, 0 errors, 0 skips

テストが失敗した文字列も出力されてる。(出力するようにしたので)

ユーザーモデルのメールアドレスのフォーマットを検証するコードを追加する。
ここで正規表現の登場。
(テストは実際に取りうる値を考えて作成する、って方針なのかー)

正規表現はそれだけで別途学習が要るよね…じっくり読めば分かるけどぱっと見はよく分からない。。。

app/models/user.rb

  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, length: { maximum: 255 },
                    format: { with: VALID_EMAIL_REGEX }

テスト再実行。

$ bundle exec rake test:models
7 tests, 15 assertions, 0 failures, 0 errors, 0 skips

テストOK!

foo@bar..comのようなドットの連続を誤りとして検出できません。この問題の修正するにはとてつもなく複雑な正規表現を使う必要がありますが、これは演習問題に回します。

そうですか。。。
正規表現の理解も要りそうだなぁ…。

今日の作業時間は【28分】

次は「6.2.5 一意性を検証する」から。