0
0

More than 1 year has passed since last update.

railsチュートリアル第6章 存在性を検証する

Posted at

存在性を検証する

最も基本的なバリデーションは「存在性(Presence)」です。
これは単に、渡された属性が存在することを検証します。
例えばこの節では、ユーザーがデータベースに保存される前にnameとemailフィールドの両方が存在することを保証します。
ここではこの要求を新しいユーザーを作るためのユーザー登録フォームにまで徹底させる方法を確認します。
まずはname属性の存在性に関するテストを追加します。
具体的にはリスト 6.7のように、まず@user変数のname属性に対して空白の文字列をセットします。
そして、assert_notメソッドを使って Userオブジェクトが有効でなくなったことを確認します。

name属性にバリデーションに対するテスト

require 'test_helper'

class UserTest < ActiveSupport::TestCase
  def setup
    @user = User.new(name: "Example User", email: "user@example.com")
  end

  test "should be valid" do
    assert @user.valid?
    # Userオブジェクトの有効性を調べる。
  end

  test "name should be present" do
    @user.name = "     "
    assert_not @user.valid?

  end  
end
ubuntu:~/environment/sample_app (modeling-users) $ rails test:models
Started with run options --seed 24064

 FAIL["test_name_should_be_present", #<Minitest::Reporters::Suite:0x000055b2fa9fc588 @name="UserTest">, 0.036220663999984026]
 test_name_should_be_present#UserTest (0.04s)
        Expected true to be nil or false
        test/models/user_test.rb:14:in `block in <class:UserTest>'

  2/2: [==============================] 100% Time: 00:00:00, Time: 00:00:00

Finished in 0.04021s
2 tests, 2 assertions, 1 failures, 0 errors, 0 skips

name属性の存在を検査する方法は、リスト 6.9に示したとおり、
validates メソッドにpresence: trueという引数を与えて使うことです。
presence: trueという引数は、要素が1つのオプションハッシュです。
メソッドの最後の引数としてハッシュを渡す場合、波カッコを付けなくても問題ありません。

name属性の存在性を検証する

class User < ApplicationRecord
  validates :name, presence: true
end

validatesは単なるメソッドです。カッコを使ってリスト 6.9を同等のコードに書き換えたものを次に示します。

class User < ApplicationRecord
  validates(:name, presence: true)
end

カッコが省略できる。

>> user = User.new(name: "", email: "michael@example.com")
   (0.1ms)  begin transaction
=> #<User id: nil, name: "", email: "michael@example.com", created_at: nil, updated_at: nil>
>> user.valid?
=> false

user変数が有効かどうかをvalid?メソッドでチェックすることができます。
もしオブジェクトが1つ以上の検証に失敗したときは、falseを返します。
また、すべてのバリデーションに通ったときにtrueを返します。
今回の場合、検証が1つしかないので、どの検証が失敗したかわかります。
しかし、失敗したときに作られるerrorsオブジェクトを使って確認すれば、便利。

>> user.errors.full_messages
=> ["Name can't be blank"]
>> user.save
=> false
ubuntu:~/environment/sample_app (modeling-users) $ rails test:models
Started with run options --seed 32299

  2/2: [==============================] 100% Time: 00:00:00, Time: 00:00:00

Finished in 0.04125s
2 tests, 2 assertions, 0 failures, 0 errors, 0 skips

email属性の存在性についてもテストを書いてみましょう。
最初は失敗しますが、コードを追加することで成功する

email属性の検証に対するテスト

require 'test_helper'

class UserTest < ActiveSupport::TestCase
  def setup
    @user = User.new(name: "Example User", email: "user@example.com")
  end

  test "should be valid" do
    assert @user.valid?
  end

  test "name should be present" do
    @user.name = ""
    assert_not @user.valid?
  end  

  test "email should be present" do
    @user.email = "     "
    assert_not @user.valid?
  end
end

email属性の存在性を検証する

class User < ApplicationRecord
  validates :name, presence: true
  validates :email, presence: true
end
ubuntu:~/environment/sample_app (modeling-users) $ rails t
Running via Spring preloader in process 6088
Started with run options --seed 7475

  11/11: [============================] 100% Time: 00:00:01, Time: 00:00:01

Finished in 1.93017s
11 tests, 22 assertions, 0 failures, 0 errors, 0 skips

演習

1.新しいユーザーuを作成し、作成した時点では有効ではない(invalid)ことを確認してください。
なぜ有効ではないのでしょうか? エラーメッセージを確認してみましょう。

2.u.errors.messagesを実行すると、ハッシュ形式でエラーが取得できることを確認してください。
emailに関するエラー情報だけを取得したい場合、どうやって取得すれば良いでしょうか?

>> u = User.new(name: "", email: "")
   (0.1ms)  begin transaction
=> #<User id: nil, name: "", email: "", created_at: nil, updated_at: nil>
>> u.errors.full_messages
=> []
#どう言う意味? 両方空という意味なのかな。
>> u.email = "abc@def.com"
=> "abc@def.com"
>> u.save
=> false
>> u.save
=> false
>> u
=> #<User id: nil, name: "", email: "abc@def.com", created_at: nil, updated_at: nil>
>> u.errors.full_messages
=> ["Name can't be blank"]
#名前が空
>> u.email = ""
=> ""
>> u
=> #<User id: nil, name: "", email: "", created_at: nil, updated_at: nil>
>> u.name = "abc"
=> "abc"
>> u
=> #<User id: nil, name: "abc", email: "", created_at: nil, updated_at: nil>
>> u.errors.full_messages
=> ["Name can't be blank"]
>> u.save
=> false
#保存されていないはずなのに
#↓はなんで結果が変わるの?
>> u.errors.full_messages
=> ["Email can't be blank"]
#emailが空
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0