LoginSignup
0
0

More than 3 years have passed since last update.

Ruby on Rails Tutorial 7章

Posted at

7.1.1
演習
ブラウザから /about にアクセスし、デバッグ情報が表示されていることを確認してください。このページを表示するとき、どのコントローラとアクションが使われていたでしょうか? paramsの内容から確認してみましょう。

Railsコンソールを開き、データベースから最初のユーザー情報を取得し、変数userに格納してください。その後、puts user.attributes.to_yamlを実行すると何が表示されますか? ここで表示された結果と、yメソッドを使ったy user.attributesの実行結果を比較してみましょう。

1

 controller: static_pages
 action: about


>> user = User.first
  User Load (0.1ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> #<User id: 1, name: "El Duderino", email: "mhartl@example.com", created_at: "2019-04-11 07:54:02", updated_at: "2019-04-11 08:43:38", password_digest: "$2a$10$hO4Ic/m6emGj03egTvc/5.b1zZgS/Gzff3S7MH9srwr...">

>> puts user.attributes.to_yaml
---
id: 1
name: El Duderino
email: mhartl@example.com
created_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &1 2019-04-11 07:54:02.131736000 Z
  zone: &2 !ruby/object:ActiveSupport::TimeZone
    name: Etc/UTC
  time: *1
updated_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &3 2019-04-11 08:43:38.448201000 Z
  zone: *2
  time: *3
password_digest: "$2a$10$hO4Ic/m6emGj03egTvc/5.b1zZgS/Gzff3S7MH9srwrBuVoZj69kO"
=> nil
>> 

7.1.2

演習
埋め込みRubyを使って、マジックカラム (created_atとupdated_at) の値をshowページに表示してみましょう (リスト 7.4)。
埋め込みRubyを使って、Time.nowの結果をshowページに表示してみましょう。ページを更新すると、その結果はどう変わっていますか? 確認してみてください。

1 改行しないでまとめて表示したのをコピペ

El Duderino, mhartl@example.com2019-04-11 07:54:02 UTC, 2019-04-11 08:43:38 UTC2019-04-12 02:58:33 +0000

7.1.3
演習
showアクションの中にdebuggerを差し込み (リスト 7.6)、ブラウザから /users/1 にアクセスしてみましょう。その後コンソールに移り、putsメソッドを使ってparamsハッシュの中身をYAML形式で表示してみましょう。ヒント: 7.1.1.1の演習を参考にしてください。その演習ではdebugメソッドで表示したデバッグ情報を、どのようにしてYAML形式で表示していたでしょうか?
newアクションの中にdebuggerを差し込み、/users/new にアクセスしてみましょう。@userの内容はどのようになっているでしょうか? 確認してみてください。

確認

7.1.4
演習
(任意) Gravatar上にアカウントを作成し、あなたのメールアドレスと適当な画像を紐付けてみてください。メールアドレスをMD5ハッシュ化して、紐付けた画像がちゃんと表示されるかどうか試してみましょう。

7.1.4で定義したgravatar_forヘルパーをリスト 7.12のように変更して、sizeをオプション引数として受け取れるようにしてみましょう。うまく変更できると、gravatar_for user, size: 50といった呼び出し方ができるようになります。重要: この改善したヘルパーは10.3.1で実際に使います。忘れずに実装しておきましょう。

オプション引数は今でもRubyコミュニティで一般的に使われていますが、Ruby 2.0から導入された新機能「キーワード引数 (Keyword Arguments)」でも実現することができます。先ほど変更したリスト 7.12を、リスト 7.13のように置き換えてもうまく動くことを確認してみましょう。この2つの実装方法はどういった違いがあるのでしょうか? 考えてみてください。

確認なので省略

7.1.2
演習
試しに、リスト 7.15にある:nameを:nomeに置き換えてみましょう。どんなエラーメッセージが表示されるようになりますか?

試しに、ブロックの変数fをすべてfoobarに置き換えてみて、結果が変わらないことを確認してみてください。確かに結果は変わりませんが、変数名をfoobarとするのはあまり良い変更ではなさそうですね。その理由について考えてみてください。

railschapter77.1.2x_2019-4-12_14-25-31_No-00.png


formのfをさしているのでわかりにくい変数名を付けるべきでない

7.2.2
演習
Learn Enough HTML to Be DangerousではHTMLをすべて手動で書き起こしていますが、なぜformタグを使わなかったのでしょうか? 理由を考えてみてください。

入力欄がなく送信する情報がないのでformタグを使う必要がないから

7.3.2

演習
1./signup?admin=1 にアクセスし、paramsの中にadmin属性が含まれていることをデバッグ情報から確認してみましょう。


Started GET "/signup?admin=1" for 49.251.69.218 at 2019-04-12 09:38:14 +0000
Cannot render console from 49.251.69.218! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255

7.3.3

演習
最小文字数を5に変更すると、エラーメッセージも自動的に更新されることを確かめてみましょう。
未送信のユーザー登録フォーム (図 7.12) のURLと、送信済みのユーザー登録フォーム (図 7.18) のURLを比べてみましょう。なぜURLは違っているのでしょうか? 考えてみてください。

1
表示されるエラー

The form contains 1 error.
Password is too short (minimum is 5 characters)


未送信のユーザー登録フォーム のURLは以下。 "・・・/signup"
ルーティングの以下が実行されている。

送信済みのユーザー登録フォーム のURLは以下。 "・・・/users"
ルーティングの以下が実行されている。

7.3.4
演習
リスト 7.20で実装したエラーメッセージに対するテストを書いてみてください。どのくらい細かくテストするかはお任せします。リスト 7.25にテンプレートを用意しておいたので、参考にしてください。

ユーザー登録フォームのURLは /signup ですが、無効なユーザー登録データを送付するとURLが /users に変わってしまいます。これはリスト 5.43で追加した名前付きルート (/signup) と、RESTfulなルーティング (リスト 7.3) のデフォルト設定との差異によって生じた結果です。リスト 7.26とリスト 7.27の内容を参考に、この問題を解決してみてください。うまくいけばどちらのURLも /signup になるはずです。あれ、でもテストは greenのままになっていますね...、なぜでしょうか? (考えてみてください)

リスト 7.25のpost部分を変更して、先ほどの演習課題で作った新しいURL (/signup) に合わせてみましょう。また、テストが greenのままになっている点も確認してください。

リスト 7.27のフォームを以前の状態 (リスト 7.20) に戻してみて、テストがやはり greenになっていることを確認してください。これは問題です! なぜなら、現在postが送信されているURLは正しくないのですから。assert_selectを使ったテストをリスト 7.25に追加し、このバグを検知できるようにしてみましょう (テストを追加して redになれば成功です)。その後、変更後のフォーム (リスト 7.27) に戻してみて、テストが green になることを確認してみましょう。ヒント: フォームから送信してテストするのではなく、’form[action="/signup"]’という部分が存在するかどうかに着目してテストしてみましょう。

  test "invalid signup information" do
    get signup_path
    assert_no_difference 'User.count' do
      post users_path, params: { user: { name: "",
                                  email: "user@invalid",
                                  password: "foo",
                                  password_confirmation: "bar" } }
    end
    assert_template 'users/new'
    assert_select 'div#error_explanation'
    assert_select 'div.field_with_errors'
    assert_select 'ul' do
      assert_select 'li', 'Name can\'t be blank'
      assert_select 'li', 'Email is invalid'
      assert_select 'li', 'Password confirmation doesn\'t match Password'
      assert_select 'li', 'Password is too short (minimum is 6 characters)'
    end
  end

7.4.2
演習
コンソールに移り、文字列内の式展開 (4.2.2) でシンボルを呼び出してみましょう。例えば"#{:success}"といったコードを実行すると、どんな値が返ってきますか? 確認してみてください。
先ほどの演習で試した結果を参考に、リスト 7.30のflashはどのような結果になるか考えてみてください。

1


>> "#{:success}"
=> "success"


>> flash = { success: "It worked!", danger: "It failed." }
=> {:success=>"It worked!", :danger=>"It failed."}
>> "#{flash[:success]}"
=> "It worked!"
>> "#{flash[:danger]}"
=> "It failed."
>> 

7.4.3演習
1. Railsコンソールを使って、新しいユーザーが本当に作成されたのかもう一度チェックしてみましょう。結果は、リスト 7.32のようになるはずです。


>> User.find_by(email: "example@railstutorial.org")
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."email" = ? LIMIT ?  [["email", "example@railstutorial.org"], ["LIMIT", 1]]
=> #<User id: 1, name: "Rails Tutorial", email: "example@railstutorial.org", created_at: "2019-04-13 05:30:47", updated_at: "2019-04-13 05:30:47", password_digest: "$2a$10$gr18EYrgzmjFoagV/HyQXuXMbr7DZgH5Y.kPFwBibpn...">

7.4.4

演習
7.4.2で実装したflashに対するテストを書いてみてください。どのくらい細かくテストするかはお任せします。リスト 7.34に最小限のテンプレートを用意しておいたので、参考にしてください (FILL_INの部分を適切なコードに置き換えると完成します)。ちなみに、テキストに対するテストは壊れやすいです。文量の少ないflashのキーであっても、それは同じです。筆者の場合、flashが空でないかをテストするだけの場合が多いです。
本文中でも指摘しましたが、flash用のHTML (リスト 7.31) は読みにくいです。より読みやすくしたリスト 7.35のコードに変更してみましょう。変更が終わったらテストスイートを実行し、正常に動作することを確認してください。なお、このコードでは、Railsのcontent_tagというヘルパーを使っています。
リスト 7.28のリダイレクトの行をコメントアウトすると、テストが失敗することを確認してみましょう。
リスト 7.28で、@user.saveの部分をfalseに置き換えたとしましょう (バグを埋め込んでしまったと仮定してください)。このとき、assert_differenceのテストではどのようにしてこのバグを検知するでしょうか? テストコードを追って考えてみてください。

test/integration/users_test.rb

  test "valid signup information" do
    get signup_path
    assert_difference 'User.count', 1 do
      post users_path, params: { user: { name:  "Example User",
                                         email: "user@example.com",
                                         password:              "password",
                                         password_confirmation: "password" } }
    end
    follow_redirect!
    assert_template 'users/show'
    assert_not flash.empty?
  end
end

@user.saveをコメントアウトすると出るエラーメッセージ



ec2-user:~/environment/sample_app (sign-up) $ rails t
Running via Spring preloader in process 23008
Started with run options --seed 15913

 FAIL["test_invalid_signup_information", UsersSignupTest, 0.48565702699124813]
 test_invalid_signup_information#UsersSignupTest (0.49s)
        expecting <"users/new"> but rendering with <[]>
        test/integration/users_signup_test.rb:13:in `block in <class:UsersSignupTest>'

 FAIL["test_valid_signup_information", UsersSignupTest, 0.4982957169995643]
 test_valid_signup_information#UsersSignupTest (0.50s)
        "User.count" didn't change by 1.
        Expected: 1
          Actual: 0
        test/integration/users_signup_test.rb:21:in `block in <class:UsersSignupTest>'

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

Finished in 0.54846s
18 tests, 34 assertions, 2 failures, 0 errors, 0 skips

User.count" didn't change by 1.とあるようsaveされなかったのでuser.countが1増えず、エラーになる

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