Ruby on Rails チュートリアル(第4版)　第7章

##7.1.1　演習
1.ブラウザから /about にアクセスし、デバッグ情報が表示されていることを確認してください。このページを表示するとき、どのコントローラとアクションが使われていたでしょうか? paramsの内容から確認してみましょう。
　`controller: static_pages`
　`action: about`
2.Railsコンソールを開き、データベースから最初のユーザー情報を取得し、変数userに格納してください。その後、puts user.attributes.to_yamlを実行すると何が表示されますか? ここで表示された結果と、yメソッドを使ったy user.attributesの実行結果を比較してみましょう。

```
>> puts user.attributes.to_yaml
---
id: 1
name: Michael Hartl
email: mhartl@example.jp
created_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &1 2020-07-04 13:19:58.704260000 Z
  zone: &2 !ruby/object:ActiveSupport::TimeZone
    name: Etc/UTC
  time: *1
updated_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &3 2020-07-04 13:29:40.208038000 Z
  zone: *2
  time: *3
password_digest: "$2a$10$lIblqgEiCfLVJhfbugPd/epzBk4kR7Vi6bMYF8e2Yjb3iIkPwLrS6"
=> nil
```

```
>> y user.attributes
---
id: 1
name: Michael Hartl
email: mhartl@example.jp
created_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &1 2020-07-04 13:19:58.704260000 Z
  zone: &2 !ruby/object:ActiveSupport::TimeZone
    name: Etc/UTC
  time: *1
updated_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &3 2020-07-04 13:29:40.208038000 Z
  zone: *2
  time: *3
password_digest: "$2a$10$lIblqgEiCfLVJhfbugPd/epzBk4kR7Vi6bMYF8e2Yjb3iIkPwLrS6"
=> nil
```

##7.1.2　演習
1.埋め込みRubyを使って、マジックカラム (created_atとupdated_at) の値をshowページに表示してみましょう (リスト 7.4)。

```ruby:/app/views/users/show.html.erb
<%= @user.name %>, <%= @user.email %><%= @user.created_at %><%= @user.updated_at %>
```

2.埋め込みRubyを使って、Time.nowの結果をshowページに表示してみましょう。ページを更新すると、その結果はどう変わっていますか? 確認してみてください。
　秒数が進む。日本の時間とはズレているみたい。

```
<%= @user.name %>, <%= @user.email %><%= @user.created_at %><%= @user.updated_at %><%= Time.now %>
```


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

```
(byebug) puts @user.attributes.to_yaml
---
id: 1
name: Michael Hartl
email: mhartl@example.jp
created_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &1 2020-07-04 13:19:58.704260000 Z
  zone: &2 !ruby/object:ActiveSupport::TimeZone
    name: Etc/UTC
  time: *1
updated_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &3 2020-07-04 13:29:40.208038000 Z
  zone: *2
  time: *3
password_digest: "$2a$10$lIblqgEiCfLVJhfbugPd/epzBk4kR7Vi6bMYF8e2Yjb3iIkPwLrS6"
nil
```

2.newアクションの中にdebuggerを差し込み、/users/new にアクセスしてみましょう。@userの内容はどのようになっているでしょうか? 確認してみてください。

```
(byebug) @user
Started GET "/users/new" for 182.168.132.37 at 2020-07-10 13:03:56 +0000
#<User id: 1, name: "Michael Hartl", email: "mhartl@example.jp", created_at: "2020-07-04 13:19:58", updated_at: "2020-07-04 13:29:40", password_digest: "$2a$10$lIblqgEiCfLVJhfbugPd/epzBk4kR7Vi6bMYF8e2Yjb...">
```

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

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

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

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

`undefined method `nome' for #<User:0x00007ff659c23830>`

2.試しに、ブロックの変数fをすべてfoobarに置き換えてみて、結果が変わらないことを確認してみてください。確かに結果は変わりませんが、変数名をfoobarとするのはあまり良い変更ではなさそうですね。その理由について考えてみてください。
　考えよう演習は正解が分からないので難しい。
　Formの変数名なので関係ないfoobarはあまり良くない、という感じなのかな？

##7.2.2　演習
1.Learn Enough HTML to Be DangerousではHTMLをすべて手動で書き起こしていますが、なぜformタグを使わなかったのでしょうか? 理由を考えてみてください。
　Formタグは便利だけど、勝手に考えてコードを作ってくれる＝仕組みをちゃんと理解出来ないから。
　なのかな。Rails凄い。



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

##7.3.3　演習
1.最小文字数を5に変更すると、エラーメッセージも自動的に更新されることを確かめてみましょう。
 
```ruby:/app/models/user.rb
validates :password, presence: true, length: { minimum: 5 }
```

`Password is too short (minimum is 5 characters)`

2.未送信のユーザー登録フォーム (図 7.12) のURLと、送信済みのユーザー登録フォーム (図 7.18) のURLを比べてみましょう。なぜURLは違っているのでしょうか? 考えてみてください。
　newアクション→createアクションに変わったから。

##7.3.4　演習
1.リスト 7.20で実装したエラーメッセージに対するテストを書いてみてください。どのくらい細かくテストするかはお任せします。リスト 7.25にテンプレートを用意しておいたので、参考にしてください。
 考えたけど良く分からずカンニングしてしまいました。
　[エラーメッセージに対するテスト: Railsチュートリアル備忘録 - 7章](https://qiita.com/daddy_hacker/items/8578133f6ece5752bda5)
 　`assert_select`でHTMLのタグの中身を確認する
　エラーだったときに下記のdivが展開されてるかどうかのテストかな。

```
<div id="error_explanation">
<div class="alert alert-danger">
``` 

```ruby:/sample_app/test/integration/users_signup_test.rb
assert_select 'div#error_explanation'
assert_select 'div.alert'
```

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

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

```ruby:/test/integration/users_signup_test.rb
post signup_path, params: { user: { name:  "",
                                    email: "user@invalid",
                                    password:              "foo",
                                    password_confirmation: "bar" } }
```

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

```ruby:/sample_app/test/integration/users_signup_test.rb
assert_select 'form[action="/signup"]'
```

##7.4.1　演習
1.有効な情報を送信し、ユーザーが実際に作成されたことを、Railsコンソールを使って確認してみましょう。
　省略
2.リスト 7.28を更新し、redirect_to user_url(@user)とredirect_to @userが同じ結果になることを確認してみましょう。
　省略

##7.4.3　演習
1.コンソールに移り、文字列内の式展開 (4.2.2) でシンボルを呼び出してみましょう。例えば"#{:success}"といったコードを実行すると、どんな値が返ってきますか? 確認してみてください。

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

2.先ほどの演習で試した結果を参考に、リスト 7.30のflashはどのような結果になるか考えてみてください。
　valueの値の文字列が返ってくる。

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

2.自分のメールアドレスでユーザー登録を試してみましょう。既にGravatarに登録している場合、適切な画像が表示されているか確認してみてください。
　省略

##7.4.4　演習
1.7.4.2で実装したflashに対するテストを書いてみてください。どのくらい細かくテストするかはお任せします。リスト 7.34に最小限のテンプレートを用意しておいたので、参考にしてください (FILL_INの部分を適切なコードに置き換えると完成します)。ちなみに、テキストに対するテストは壊れやすいです。文量の少ないflashのキーであっても、それは同じです。筆者の場合、flashが空でないかをテストするだけの場合が多いです。

```ruby:/test/integration/users_signup_test.rb
assert_not flash.empty?
```

2.本文中でも指摘しましたが、flash用のHTML (リスト 7.31) は読みにくいです。より読みやすくしたリスト 7.35のコードに変更してみましょう。変更が終わったらテストスイートを実行し、正常に動作することを確認してください。なお、このコードでは、Railsのcontent_tagというヘルパーを使っています。
　省略

3.リスト 7.28のリダイレクトの行をコメントアウトすると、テストが失敗することを確認してみましょう。
　REDになる。

4.リスト 7.28で、@user.saveの部分をfalseに置き換えたとしましょう (バグを埋め込んでしまったと仮定してください)。このとき、assert_differenceのテストではどのようにしてこのバグを検知するでしょうか? テストコードを追って考えてみてください。
　`'User.count', 1`にならないのを検知する。

##またしてもエラー
`heroku run rails db:migrate`がまたうまくいかない。前章でもエラーが。何故だろう。
前章と同じく、[heroku command not found の対処](https://qiita.com/RyuGotoo/items/7d44f7aa51f7c90ad0b7)を参考に。

##7.5.3　演習
1.ブラウザから本番環境 (Heroku) にアクセスし、SSLの鍵マークがかかっているか、URLがhttpsになっているかどうかを確認してみましょう。
　無事デプロイ出来て、確認出来た。

2.本番環境でユーザーを作成してみましょう。Gravatarの画像は正しく表示されているでしょうか?
　省略

##メモ
- Railsには標準で3つ環境が備わっており、それぞれ開発環境 (development)、テスト環境 (test)、本番環境 (production)と呼ぶ
- `any?`メソッドはちょうど`empty?`と逆の動作で、要素が1つでもある場合はtrue、ない場合はfalseを返す。