Railsチュートリアル 第１０章＜復習＞

第１０章の復習メモです。
個人的に重要と思ったことを書きます。

前回と同様、以下３つの視点で書きます。

- 分かったこと
- 分からなかったこと
- 今回はスルーしたこと


#分かったこと

##PATCHリクエストについて

ユーザの新規作成画面（`app/views/users/new.html.erb`）と、編集画面（`app/views/users/edit.html.erb`）は、画面項目が同じなため、フォームを部分テンプレートに共通化した。

```app/views/users/_form.html.erb
<%= form_for(@user) do |f| %>
  <%= render 'shared/error_messages', object: @user %>

  <%= f.label :name %>
  <%= f.text_field :name, class: 'form-control' %>

  <%= f.label :email %>
  <%= f.email_field :email, class: 'form-control' %>

  <%= f.label :password %>
  <%= f.password_field :password, class: 'form-control' %>

  <%= f.label :password_confirmation %>
  <%= f.password_field :password_confirmation, class: 'form-control' %>

  <%= f.submit yield(:button_text), class: "btn btn-primary" %>
<% end %>
```

共通化により懸念されるのが、

- リクエスト先URLの違い
- リクエストのメソッドの違い

ルーティングについて、７章で以下のように設定した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506678/f05ff410-5e71-494b-3aeb-92cdfac19e24.png)

これらの違いがあるので、普通に考えたら、分岐の処理を入れる必要がある。しかし、これについては**Railsが上手くやってくれる**。

> Railsは、form_for(@user)を使ってフォームを構成すると、@user.new_record?がtrueのときにはPOSTを、falseのときにはPATCHを使います。

##DBへのデータ一括登録

画面やコンソールから一件ずつ登録せずとも、DBにデータを一括登録する方法がある。
手順は以下の通り。

1. Gemfileにgemを追加する
2. 登録したいデータを用意する
3. DBに反映させる

###手順1. Gemfileにgemを追加する

`Faker gem`を追加する

```
source 'https://rubygems.org'

gem 'rails',          '5.1.6'
gem 'bcrypt',         '3.1.12'
gem 'faker',          '1.7.3'  # ← これを追加
.
.
.
```

###手順2. 登録したいデータを用意する

`db/seeds.rb`ファイルに、登録したいデータを記載する

```db/seeds.rb
User.create!(name:  "Example User",
             email: "example@railstutorial.org",
             password:              "foobar",
             password_confirmation: "foobar")

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
```

Example Userという名前とメールアドレスを持つ1人のユーザと、それらしい名前とメールアドレスを持つ99人のユーザーを作成している。

###手順3. DBに反映させる

現在登録されているデータを消しておきたい場合、

```
$ rails db:migrate:reset
```

を実行する。

手順2をDBに反映させるには、

```
$ rails db:seed
```

を実行する。

##ページネーション

一覧画面で、表示件数を区切って出力できる。手順は以下の通り。

1. Gemfileにgemを追加する
2. ビュー、コントローラを編集する

###手順1. Gemfileにgemを追加する

`will_paginate gem`、`bootstrap-will_paginate gem`を追加する

```
source 'https://rubygems.org'

gem 'rails',                   '5.1.6'
gem 'bcrypt',                  '3.1.12'
gem 'faker',                   '1.7.3'
gem 'will_paginate',           '3.1.6'  # ← これを追加
gem 'bootstrap-will_paginate', '1.0.0'  # ← これを追加
.
.
.
```

###手順2. ビュー、コントローラを編集する

###ビューに処理を追記

```app/views/users/index.html.erb
<% provide(:title, 'All users') %>
<h1>All users</h1>

<%= will_paginate %>

<ul class="users">         # ← これを追加
  <% @users.each do |user| %>
    <li>
      <%= gravatar_for user, size: 50 %>
      <%= link_to user.name, user %>
    </li>
  <% end %>
</ul>

<%= will_paginate %>       # ← これを追加
```

Railsチュートリアルの説明を引用
> このwill_paginateメソッドは少々不思議なことに、usersビューのコードの中から@usersオブジェクトを自動的に見つけ出し、それから他のページにアクセスするためのページネーションリンクを作成しています。

###コントローラの処理を変更

```app/controllers/users_controller.rb
class UsersController < ApplicationController
  before_action :logged_in_user, only: [:index, :edit, :update]
  .
  .
  .
  def index
    @users = User.paginate(page: params[:page])  # ← ここを変更
  end
  .
  .
  .
end
```

Railsチュートリアルの説明を引用
> paginateでは、キーが:pageで値がページ番号のハッシュを引数に取ります。User.paginateは、:pageパラメーターに基いて、データベースからひとかたまりのデータ (デフォルトでは30) を取り出します。
paginateを使うことで、サンプルアプリケーションのユーザーのページネーションを行えるようになります。具体的には、indexアクション内のallをpaginateメソッドに置き換えます。ここで:pageパラメーターにはparams[:page]が使われていますが、これはwill_paginateによって自動的に生成されます。

##モデルの論理値属性

モデルの属性に、**論理値（boolean）**を設定できる。

###migrationファイルの作成

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

###migrationファイルの編集

`default: false`を追加することで、全レコードfalse（0）で登録できる。

```db/migrate/[timestamp]_add_admin_to_users.rb
class AddAdminToUsers < ActiveRecord::Migration[5.0]
  def change
    add_column :users, :admin, :boolean, default: false
  end
end
```

###属性の状態を確認

`<インスタンス>.<属性>?`メソッドで、属性の状態を確認できる。

```
$ rails console --sandbox
>> user = User.first
>> user.admin?
=> false
```


#分からなかったこと、今回はスルーしたこと

- Strong Parameters
- テスト全般
- アプリケーションの仕様、ロジックの詳細