Ruby
Rails
RubyOnRails
Railsチュートリアル

Ruby on Rails チュートリアル 5.0(第4版)6.2演習

More than 1 year has passed since last update.

Ruby on Rails チュートリアル 5.0(第4版)を学習中です。
演習問題を自分なりに実施しました。
もし間違い等あればコメントいただけると嬉しいです。

演習6.2.1.1

<問題>
コンソールから、新しく生成したuserオブジェクトが有効 (valid) であることを確認してみましょう。

<解答>

>> user=User.new(name:"Taro Yamada")                                                                              
=> #<User id: nil, name: "Taro Yamada", email: nil, created_at: nil, updated_at: nil>

>> user.valid?
=> true

演習6.2.1.2

<問題>
6.1.3で生成したuserオブジェクトも有効であるかどうか、確認してみましょう。

<解答>

>> User.new
=> #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil>

>> user = User.new(name: "Michael Hartl", email: "mhartl@example.com")
=> #<User id: nil, name: "Michael Hartl", email: "mhartl@example.com", created_at: nil, updated_at: nil>

>> user.valid?
=> true

演習6.2.2.1

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

<解答>

>> u=User.new
=> #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil>

>> u.valid?
=> false

>> u.errors.full_messages
=> ["Name can't be blank", "Email can't be blank"]

演習6.2.2.2

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

<解答>

>> u.errors.messages
=> {:name=>["can't be blank"], :email=>["can't be blank"]}

>> u.errors.messages[:email]
=> ["can't be blank"]

演習6.2.3.1

<問題>
長すぎるnameとemail属性を持ったuserオブジェクトを生成し、有効でないことを確認してみましょう。

<解答>

>> user=User.new(name:"123456789012345678901234567890123456789012345678901",email:"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890@mail.com")
=> #<User id: nil, name: "12345678901234567890123456789012345678901234567890...", email: "12345678901234567890123456789012345678901234567890...", created_at: nil, updated_at: nil>

>> user.valid?
=> false

演習6.2.3.2

<問題>
長さに関するバリデーションが失敗した時、どんなエラーメッセージが生成されるでしょうか? 確認してみてください。

<解答>

>> user.errors.full_messages
=> ["Name is too long (maximum is 50 characters)", "Email is too long (maximum is 255 characters)"]

演習6.2.4.1

<問題>
リスト 6.18にある有効なメールアドレスのリストと、リスト 6.19にある無効なメールアドレスのリストをRubularのYour test string:に転記してみてください。その後、リスト 6.21の正規表現をYour regular expression:に転記して、有効なメールアドレスのみがすべてマッチし、無効なメールアドレスはすべてマッチしないことを確認してみましょう。

<解答>
FireShot Capture 400 - Rubular_ a Ruby regular expression editor and test_ - http___www.rubular.com_.png

演習6.2.4.2

<問題>
先ほど触れたように、リスト 6.21のメールアドレスチェックする正規表現は、foo@bar..comのようにドットが連続した無効なメールアドレスを許容してしまいます。まずは、このメールアドレスをリスト 6.19の無効なメールアドレスリストに追加し、これによってテストが失敗することを確認してください。次に、リスト 6.23で示した、少し複雑な正規表現を使ってこのテストがパスすることを確認してください。
<解答>
"foo@bar..com"を追加。

user_test.rb
require 'test_helper'

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

(中略)

  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 foo@bar..com]
    invalid_addresses.each do |invalid_address|
      @user.email = invalid_address
      assert_not @user.valid?, "#{invalid_address.inspect} should be invalid"
    end
  end 
end
RED
$ rails test:models

 FAIL["test_email_validation_should_reject_invalid_addresses", UserTest, 0.03081181098241359]
 test_email_validation_should_reject_invalid_addresses#UserTest (0.03s)
        "foo@bar..com" should be invalid
(中略)
[=====================================================================] 
7 tests, 16 assertions, 1 failures, 0 errors, 0 skips

リスト 6.23のとおり修正してテスト。

GREEN
$ rails test:models
(中略)
[=====================================================================] 
7 tests, 16 assertions, 0 failures, 0 errors, 0 skips

演習6.2.4.3

<問題>
foo@bar..comをRubularのメールアドレスのリストに追加し、リスト 6.23の正規表現をRubularで使ってみてください。有効なメールアドレスのみがすべてマッチし、無効なメールアドレスはすべてマッチしないことを確認してみましょう。

<解答>

FireShot Capture 403 - Rubular_ a Ruby regular expression editor and test_ - http___www.rubular.com_.png

演習6.2.5.1

<問題>
リスト 6.33を参考に、メールアドレスを小文字にするテストをリスト 6.32に追加してみましょう。ちなみに追加するテストコードでは、データベースの値に合わせて更新するreloadメソッドと、値が一致しているかどうか確認するassert_equalメソッドを使っています。リスト 6.33のテストがうまく動いているか確認するためにも、before_saveの行をコメントアウトして redになることを、また、コメントアウトを解除すると greenになることを確認してみましょう。

<解答>
問題の指示通り、リスト 6.33のとおり"user_test.rb"を修正。
"user.rb"のbefore_saveの行をコメントアウトし、テスト。

RED
$ rails test
(中略)
 FAIL["test_email_addresses_should_be_saved_as_lower-case", UserTest, 0.7439497619634494]
 test_email_addresses_should_be_saved_as_lower-case#UserTest (0.74s)
        Expected: "foo@example.com"
          Actual: "Foo@ExAMPle.CoM"
        test/models/user_test.rb:61:in `block in <class:UserTest>'
(中略)
[===================================================================]
(中略)
17 tests, 37 assertions, 1 failures, 0 errors, 0 skips

コメントアウト解除し、テスト。

GREEN
$ rails test
(中略)
[===================================================================]
(中略)
17 tests, 37 assertions, 0 failures, 0 errors, 0 skips

演習6.2.5.2

<問題>
テストスイートの実行結果を確認しながら、before_saveコールバックをemail.downcase!に書き換えてみましょう。ヒント: メソッドの末尾に!を付け足すことにより、email属性を直接変更できるようになります (リスト 6.34)。

<解答>
リスト6.34参照。

関連記事

Ruby on Rails チュートリアル 完全攻略 概要と演習解答総まとめ
http://mochikichi.hatenablog.com/entry/rails_tutorial_guide