Railsチュートリアル（第10章）

# はじめに
Railsチュートリアルの第10章が終わりました。
この章では、ユーザーの更新、表示、削除を行います。
ポイントだけメモしておきます。

# ユーザーの編集
まずeditアクションでidを元にユーザーを取得します。

```rb
  def edit
    @user = User.find(params[:id])
  end
```
取得したユーザーを登録時と同様に`form_for`を使用して表示します。
書き方は登録時と一緒です。

```erb
  <%= form_for(@user) do |f| %>
    ...
  <% end %>
```
この時に、`new_record?`というメソッドを使って`@user`が新規のものかすでにあるものかを判断して、自動的にcreateかupdateを分けてくれます。

登録時は以下のように、`update_attributes`で行います。
（登録時のsave相当）

```rb
  def update
    @user = User.find(params[:id])
    if @user.update_attributes(user_params)
      # 成功
    else
      # 失敗
    end
  end
```

# beforeフィルター
コントローラーの各アクションの前に呼ばれるメソッドを定義できます。
例えば、ログインされている場合だけアクションを実行する際、先にチェックメソッドを呼ぶといった使い方ができます。

以下のように、`before_action`の後に記述します。
そのままでは全てのアクションの前に呼ばれるので、限定したい場合は、後ろに`only: "メソッドシンボルの配列"`を記述します。

```rb
before_action :logged_in_user, only: [:edit, :update]

def logged_in_user
  ...
end
```

# フレンドリーフォワーディング
フレンドリーフォワーディングとは、簡単に言うと、
未ログイン時にAページに遷移
→ログインページにリダイレクト
→ログイン
→Aページに遷移
のように、本来のログイン後のページではなく、遷移しようとしていたページに遷移させることです。

以下のように、sessionにURLを保持しておくことで実装します。
未ログイン時のリダイレクトで覚えるメソッドを呼び、ログイン後のメソッドでリダイレクトのメソッドを呼びます。
以下のようにすると、URLがなければ引数に渡したデフォルトのURLにリダイレクトできます。
また、`request.original_url`で元々遷移しようとしたURLの取得、`request.get?`でGETリクエストかの判定ができます。

```rb
  # 記憶したURL (もしくはデフォルト値) にリダイレクト
  def redirect_back_or(default)
    redirect_to(session[:forwarding_url] || default)
    session.delete(:forwarding_url)
  end

  # アクセスしようとしたURLを覚えておく
  def store_location
    session[:forwarding_url] = request.original_url if request.get?
  end
```

# 一覧の表示
まずindexアクションで全てのユーザーを取得します。

```rb
  def index
    @users = User.all
  end
```
取得した`@users`を`each`で全て表示します。

```erb
  <% @users.each do |user| %>
    <li>
      <%= gravatar_for user, size: 50 %>
      <%= link_to user.name, user %>
    </li>
  <% end %>
```
上記のプログラムを以下のように書くことができます。
まず、each文の内容をパーシャルにします。その際、名前を`@users`の単数の`user`にします。

```erb:_user.html.erb
    <li>
      <%= gravatar_for user, size: 50 %>
      <%= link_to user.name, user %>
    </li>
```
そして、以下のように`render @users`と記述することで、自動的にuserのリストだと判断し1つずつパーシャルを表示します。

```erb
  <%= render @users %>
```

# サンプルユーザーの作成
サンプルのユーザーを作成するために、実際にいそうな名前を作成してくれる`faker`というgemを入れます。

```:Gemfile
gem 'faker', '1.7.3'
```
`seeds.rb`というファイルに記述することで、サンプルデータを定義することができます。
以下のように、`times`で一気に複数作成することができます。
fakerを使用しているのは`Faker::Name.name`のところです。

```rb:db/seeds.rb
99.times do |n|
  name  = Faker::Name.name
  email = "example-#{n+1}@railstutorial.org"
  password = "password"
  User.create!(name:  name,
               email: email,
               password:              password,
               password_confirmation: password)
end
```
`seeds.rb`に定義した内容をデータベースに反映するためには、以下のように`rails db:seed`を実行します。
`rails db:migrate:reset`はデータベースの内容をクリアしています。

```
rails db:migrate:reset
rails db:seed
```

# ページネーション
ページネーションを使用するために、以下の2つのgemを入れます。

```:Gemfile
gem 'will_paginate',           '3.1.6'
gem 'bootstrap-will_paginate', '1.0.0'
```
実際に使用する箇所に以下の記述を追加します。

```erb
<%= will_paginate %>
```
ただし、上記の記述だけでは表示できず、以下のように、`User.paginate(page: "ページ番号")`を使用して、そのページの一覧を取得する必要があります。

```rb
  def index
    @users = User.paginate(page: params[:page])
  end
```

# 管理者権限
以下のように、管理者権限を示す`admin`というboolean型のカラムを追加します。
boolean型を追加すると、`admin?`という真偽値を判定するメソッドが使用できます。

```
rails generate migration add_admin_to_users admin:boolean
```

# ユーザーの削除
削除する際は、destroyアクション内で、userのモデルに対して、`destroy`メソッドを呼びます。

```rb
  def destroy
    User.find(params[:id]).destroy
    flash[:success] = "User deleted"
    redirect_to users_url
  end
```