Ruby on Rails チュートリアル第７章　ユーザー登録

#ユーザー登録
　この記事ではrailsで作成したアプリのユーザー登録機能を実装する方法について説明する。
　まず、ユーザーの名前とプロフィールを表示するユーザーページを作成する。そのため、まずデータベースにユーザーが登録されている必要がある。コンソールで以下のように入力し、ユーザーを一人追加する。このユーザーのidを1とする。

```ruby
$ user = User.new(name:"YSD",email:"foobar@gmail.com",password:"foobar",password_confirmation:"foobar")
```
そしてRESTアーキテクチャの習慣に従い、ユーザー情報をプロフィールページに表示するために、

```ruby:config/routes.rb
Rails.application.routes.draw do
  root 'static_pages#home'
  get  '/help',    to: 'static_pages#help'
  get  '/about',   to: 'static_pages#about'
  get  '/contact', to: 'static_pages#contact'
  get  '/signup',  to: 'users#new'
  resources :users
end
```
configのroutesファイルにresources:usersを追加し、ユーザーリソースに対してCRUD操作（change,read,update,delete）ができるようにする。

| HTTPリクエスト | URL | アクション | 名前付きルート | 用途 |
| GET | /users | index | users_path | すべてのユーザーを一覧するページ |
| GET | /users/1 | show | user_path(user) | 特定のユーザーを表示するページ |
| GET | /users/new | new | new_user_path | ユーザーを新規作成するページ (ユーザー登録) |
| POST | /users | create | users_path | ユーザーを作成するアクション |
| GET | /users/1/edit | edit | edit_user_path(user) | id=1のユーザーを編集するページ |
| PATCH | /users/1 | update | user_path(user) | ユーザーを更新するアクション |
| DELETE | /users/1 | destroy | user_path(user) | ユーザーを削除するアクション |

結果として上のようなリクエストとURL,名前つきルートの対応関係が生成される。

　次にユーザーのプロフィールページを表示するapp/views/users/show.html.erbファイルを編集する。

```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>
```
ここではユーザーモデルのインスタンス変数@userが使われているので、Userコントローラーのshowアクションで@userを定義する必要がある。

```ruby:app/controllers/users_controller.rb
class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])
  end

  def new
  end
end
```
params変数のidキーには現在表示しているプロフィールページのユーザーのidが入る。（URLのusers/idのid）これでユーザーのビューとアクション、ルートが用意されたので、/users/1が完全に動作するようになった。
なお、showファイルのgravatar_forメソッドは、ユーザーのコントローラーに関連づけられているヘルパーファイルで定義されているメソッドで、プロフィール写真をアップロードして指定したメールアドレスと紐付けることができる無料サービスであるGravatarをRailsに導入できる。erbの<%= gravatar_for @user %>では@userのメールアドレスに対応した画像がプロフィールページに表示される。このメソッドの中身は

```ruby:app/helpers/users_helper.rb
module UsersHelper

  # 引数で与えられたユーザーのGravatar画像を返す
  def gravatar_for(user)
    gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
    gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}"
    image_tag(gravatar_url, alt: user.name, class: "gravatar")
  end
end
```
このようになっており、メールアドレスをハッシュ化したもの（gravatar_id）を含むGravatarのurlをimage_tagに渡し、対応する画像を表示するような機構になっている。

　ここでユーザー登録ページの実装を行う。すでにルーティングにより登録フォームとnewアクションは紐づけられており、ユーザー登録フォームではform_forメソッドを用い、引数に@userを取るので、コントローラーのnewアクションに@userを追加する。

```ruby:app/controllers/users_controller.rb

class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])
  end

  def new
    @user = User.new
  end
end
```
フォームそのものは、以下のようになる

```ruby:app/views/users/new.html.erb

<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_for(@user) do |f| %>
      <%= f.label :name %>
      <%= f.text_field :name %>

      <%= f.label :email %>
      <%= f.email_field :email %>

      <%= f.label :password %>
      <%= f.password_field :password %>

      <%= f.label :password_confirmation, "Confirmation" %>
      <%= f.password_field :password_confirmation %>

      <%= f.submit "Create my account", class: "btn btn-primary" %>
    <% end %>
  </div>
</div>

```
表示されるフォームは
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486493/eadfa207-89ad-937a-8562-0d0a48c49a08.png)

となる。
form_forのブロック内のfオブジェクトはHTMLフォーム要素 (テキストフィールド、ラジオボタン、パスワードフィールドなど) に対応するメソッドが呼び出されると、@userの属性を設定するために特別に設計されたHTMLを返す。

```ruby
<%= f.label :name %>
<%= f.text_field :name %>
```
例えば、このようなコードでは、Userモデルのname属性を設定する、ラベル付きテキストフィールド要素を作成するのに必要なHTMLを作成する。
結果として生成されたformのHTMLは

```html
<form accept-charset="UTF-8" action="/users" class="new_user"
      id="new_user" method="post">
  <input name="utf8" type="hidden" value="&#x2713;" />
  <input name="authenticity_token" type="hidden"
         value="NNb6+J/j46LcrgYUC60wQ2titMuJQ5lLqyAbnbAUkdo=" />
  <label for="user_name">Name</label>
  <input id="user_name" name="user[name]" type="text" />

  <label for="user_email">Email</label>
  <input id="user_email" name="user[email]" type="email" />

  <label for="user_password">Password</label>
  <input id="user_password" name="user[password]"
         type="password" />

  <label for="user_password_confirmation">Confirmation</label>
  <input id="user_password_confirmation"
         name="user[password_confirmation]" type="password" />

  <input class="btn btn-primary" name="commit" type="submit"
         value="Create my account" />
</form>
```
となり、

```html
<form accept-charset="UTF-8" action="/users" class="new_user"
      id="new_user" method="post">
```
の部分では新規ユーザー作成のためにPOSTリクエストを/usersに発行してcreateアクションを呼び出している。また、各inputのname属性の値が、paramas変数をuserハッシュのキーの値となる。例えば、

```html
<input id="user_email" name="user[email]" type="email" />
```
では、user[email]の値がuserの:emailキーの値となる。要するにnameやemailなどの各フォームに入力した内容がparams変数のuserハッシュの各キーの値となる。

そしてcreateアクションは

```ruby:app/controllers/users_controller.rb

class UsersController < ApplicationController
  .
  .
  .
  def create
    @user = User.new(params[:user])
    if @user.save
      redirect_to @user
    else
      render 'new'
    end
  end

end
```
となる。ここで、

```ruby
redirect_to @user
```
は

```ruby
redirect_to user_url(@user)
```
等価であり、もし、ユーザー登録に成功すれば、ユーザーのプロフィールページにリダイレクトされ、失敗すればユーザー登録のフォームにリダイレクトされるようになっている。
なお

```ruby
@user = User.new(params[:user])
```
は、

```ruby
@user = User.new(name: "Foo Bar", email: "foo@invalid",
                 password: "foo", password_confirmation: "bar")
```
のようなコードと等価である。