Ruby on Rails Tutorial 7章

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のように置き換えてもうまく動くことを確認してみましょう。この２つの実装方法はどういった違いがあるのでしょうか? 考えてみてください。

確認なので省略


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

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

![railschapter77.1.2x_2019-4-12_14-25-31_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368629/5e741ff2-cccd-69b8-da42-0be0dd1622f3.png)

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


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

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

7.3.2

演習
１．/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増えず、エラーになる