【Railsチュートリアル】第7章 ユーザー登録①

#第7章 ユーザー登録
##はじめに
###本章の目的
* ユーザー登録機能の追加
* HTML フォームを使ってWebアプリケーションに登録情報を送信
* ユーザーを新規作成して情報をデータベースに保存
* ユーザーを表示するためのページを作成
* 統合テストに対して、 いくつかのテストを追加

##7.1 ユーザーを表示する
本節では、ユーザーの名前とプロフィール写真を表示するためのページを作成していく。
ユーザープロフィールページの最終的な目標は、ユーザーのプロフィール写真と基本ユーザーデータ、そしてマイクロポストの一覧を表示すること。

###7.1.1 デバッグとRails環境
レイアウトにデバッグ情報を追加する。

```ruby:app/views/layouts/application.html.erb
      #もしRails.env.development（development=開発環境）だったらデバッグ情報を表示せよ
      <%= debug(params) if Rails.env.development? %>
```

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

```:debug_info
--- !ruby/object:ActionController::Parameters
parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
  controller: static_pages
  action: about
permitted: false
```

コントローラ: static_pages, アクション: about

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

```:console
>> user = User.first
   (3.6ms)  SELECT sqlite_version(*)
  User Load (3.4ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> #<User id: 1, name: "Michael Hartl", email: "michael@example.com", created_at: "2021-02-09 06:34:49", updated_at: "2021-02-09 06:34:49", password_digest: [FILTERED]>

>> puts user.attributes.to_yaml
---
id: 1
name: Michael Hartl
email: michael@example.com
created_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &1 2021-02-09 06:34:49.836041000 Z
  zone: &2 !ruby/object:ActiveSupport::TimeZone
    name: Etc/UTC
  time: *1
updated_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &3 2021-02-09 06:34:49.836041000 Z
  zone: *2
  time: *3
password_digest: "$2a$12$c6TWZz21VWw7m8bDorgz9uR3XMXaWbMdtzmV.r6krzwzy59OmF7gO"
=> nil

>> y user.attributes
---
id: 1
name: Michael Hartl
email: michael@example.com
created_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &1 2021-02-09 06:34:49.836041000 Z
  zone: &2 !ruby/object:ActiveSupport::TimeZone
    name: Etc/UTC
  time: *1
updated_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &3 2021-02-09 06:34:49.836041000 Z
  zone: *2
  time: *3
password_digest: "$2a$12$c6TWZz21VWw7m8bDorgz9uR3XMXaWbMdtzmV.r6krzwzy59OmF7gO"
=> nil
```
同じ

###7.1.2 Usersリソース
ユーザー情報をWebアプリケーション上に表示する。
**RESTアーキテクチャ**
* データの作成、表示、更新、削除をリソース（Resources）として扱う。
* HTTP標準には、これらに対応する４つの基本操作（POST、GET、PATCH、DELETE）を各アクションに割り当てていく。

ユーザーをリソースとみなす
= id=1のユーザーを参照する
= "/users/1というURLに対してGETリクエストを発行する"

```ruby:config/routes.rb
resources :users #この行を追加する
```

ユーザーのURLを生成するための多数の名前付きルート（5.3.3）と共に、RESTfulなUsersリソースで必要となるすべてのアクションが利用できるようになる

####演習 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ページに表示してみましょう。ページを更新すると、その結果はどう変わっていますか? 確認してみてください。

Michael Hartl, michael@example.com, 2021-02-09 06:34:49 UTC, 2021-02-09 06:34:49 UTC, 2021-02-12 23:11:30 +0900

(更新後)
Michael Hartl, michael@example.com, 2021-02-09 06:34:49 UTC, 2021-02-09 06:34:49 UTC, 2021-02-12 23:11:53 +0900

更新をかけると、表示時間も更新される。

###7.1.3 debuggerメソッド
debuggerメソッドを使う。

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

```:console
(byebug) p = params
<ActionController::Parameters {"controller"=>"users", "action"=>"show", "id"=>"1"} permitted: false>

(byebug) puts p.to_yaml
--- !ruby/object:ActionController::Parameters
parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
  controller: users
  action: show
  id: '1'
permitted: false
nil
```
####演習 2
newアクションの中にdebuggerを差し込み、/users/new にアクセスしてみましょう。@userの内容はどのようになっているでしょうか? 確認してみてください。

```:console
[1, 10] in /home/vagrant/work/sample_app2/app/controllers/users_controller.rb
    1: class UsersController < ApplicationController
    2: 
    3:   def show
    4:     @user = User.find(params[:id])
    5:   end
    6:   
    7:   def new
    8:     debugger
=>  9:   end
   10: end
(byebug) @user
nil
```

###7.1.4 Gravatar画像とサイドバー
＊ 各ユーザーのプロフィール写真のあたりをもう少し肉付けし、サイドバーも作り始める。
* Gravatar（Globally Recognized AVATAR）をプロフィールに導入する。

```ruby:app/views/users/show.html.erb
<% provide(:title, @user.name) %>
<h1>
  #gravatar_forヘルパーメソッドを使い@userのプロフィール画像を表示せよ
  <%= gravatar_for @user %>
  # @userのnameを表示
  <%= @user.name %>
</h1>
```

```:console
$ rails console
>> user = User.first
>> user.update(name: "Example User",
?>                        email: "example@railstutorial.org",
?>                        password: "foobar",
?>                        password_confirmation: "foobar")
=> true
```
emailでGravatar上とRailsチュートリアルのロゴを既に紐付けてある。

```ruby:app/views/users/show.html.erb
<% provide(:title, @user.name) %>
<div class="row">
  <aside class="col-md-4">
    <section class="user_info">
      <h1>
        <%= gravatar_for @user %>
        <%= @user.name %>
      </h1>
    </section>
  </aside>
</div>
```

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

1. [Gravatar](https://ja.gravatar.com/)
2. サイト下部の「Gravatarを作成」をクリック
3. アカウント開設
4. プロフィールの画像を変更
5. `Rails console`で`user`に`Gravatar`のメールアドレスをupdate
6. `rails s -b 0.0.0.0`で確認。変更されていました。

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

動作確認のみなので省略。
コードが完結になるだけだろうか？