Railsチュートリアルメモ - 第7章

[メモの目次記事はこちら](https://qiita.com/yokohama4580/items/dedfd5510080273dc2a0)

[Railsチュートリアル第7章へのリンク](https://railstutorial.jp/chapters/sign_up?version=5.1#cha-sign_up)

# 第7章 ユーザー登録
## 7.1 ユーザーを表示する
### ポイント 
#### デバッグ
- `<%= debug(params) if Rails.env.development? %>`で画面にデバッグ情報を表示できる。
    - `if Rails.env.development?`で開発環境のみに表示するよう制限している
- コントローラー内にdebuggerを記載して画面を表示すると、rails serverを起動しているコンソールがコマンド待受け状態になり、debuggerが呼び出された状態のままでrails consoleの操作を実行できる

#### Sassのミックスイン
@mixinで定義した内容を@includeで呼び出せる

```sass

@mixin box_sizing {
  -moz-box-sizing:    border-box;
  -webkit-box-sizing: border-box;
  box-sizing:         border-box;
}
/* miscellaneous */
.debug_dump {
  clear: both;
  float: left;
  width: 100%;
  margin-top: 45px;
  @include box_sizing;
}
```

#### ルーティング
`config/routes.rb`にresourceを追加すると、名前付きルートが使用可能になり、RESTに従ったいくつかのURLが使用可能になる

```config/routes.rb
Rails.application.routes.draw do

  resources :users
end
```
#### Gravatar
RailsというよりGravatarの使用方法の説明なので割愛

## 7.2 ユーザー登録フォーム
### ポイント
#### form_forによるフォームの作成
.html.erb内でform_forを使用すると、フォームを生成してくれる

.html.erb

```erb
<%= form_for(@user) do |f| %>
...
<%= f.label :name %>
<%= f.text_field :name %>
...
<% end %>
```
↓
html

```html
<form action="/users" class="new_user" id="new_user" method="post">
...
<label for="user_name">Name</label>
<input id="user_name" name="user[name]" type="text" />
...
</form>
```

- また、emailであれば、モバイル端末から入力フォームをタップすると、メールアドレスに最適化された特別なキーボードが表示される。passwordであれば、文字が隠蔽されて表示されるようにHTMLを生成してくれる。
- CSRF対策のトークンの生成も行ってくれる

#### paramsハッシュでの値の受け渡し
フォームで指定した値は`params`というハッシュに保存されてコントローラーに渡されるルールになっている（チュートリアルでの説明があまりにさらっとしすぎていて、`params`がどこで定義されているのかわからず少し混乱した）

## 7.3 ユーザー登録失敗
### ポイント
#### Strong Parameters
マスアサインメント:
DB登録・更新で複数のカラムを一括で指定して登録すること。メソッドにハッシュを渡して更新カラムと値を指定する。
意図的に重要なカラムの値を書き換えられる危険性があるため、Strong Parametersというテクニックを使ってController層で対策することが推奨されている（かつてはModel層で対策していたらしい）

```
params.require(:user).permit(:name, :email, :password, :password_confirmation)
```

#### privateキーワード
クラス内で`private`と記載された後に記載された要素はprivate属性となる（外部クラスからは見えない）

#### エラー表示
- Rails全般の慣習として、複数のビューで使われるパーシャルは専用のディレクトリ「shared」によく置かれる
- pluralizeメソッドによって、英語の単数系と複数形を良い感じに処理して表示してくれる
    - e.g. 0 errors, 1 error, 2 errors
- Railsは、無効な内容の送信によって元のページに戻されると、CSSクラスfield_with_errorsを持ったdivタグでエラー箇所を自動的に囲んでくれる
- （エラー表示とは関係ないが、）`class form-control`を追加すると、Bootstrapでフォームがきれいになる

#### Sassの@extend関数
@extendで特定の位置に属性を追加できる

```sass
.field_with_errors {
  @extend .has-error;
  .form-control {
    color: $state-danger-text;
  }
}
```

#### 統合テスト
- `rails generate integration_test users_signup`で統合テストの作成

#### assert_no_difference, assert_difference
以下のように記載することで、ブロック内の実行前後で引き数が変化していないこと、変化していることを検証できる

```ruby
assert_no_difference 'User.count' do

end
assert_difference 'User.count' do

end
```

#### assert_template
以下のように記載することで、意図どおりページが再描画されているかどうかを検証できる（エラーメッセージの表示によるDOMの差異は無視される？）

```ruby
    assert_template 'users/new'
```

## 7.4 ユーザー登録成功
### ポイント
#### redirect_to
コントローラーに以下のように記載すると、自動的に名前付きルート付きで解釈してくれる

```ruby
    if @user.save
      redirect_to @user
    else
      render 'new'
    end
```
↓

```ruby
    if @user.save
      redirect_to user_url(@user)
    else
      render 'new'
    end
```

#### flash変数
flash変数に代入したメッセージは、リダイレクトした直後のページでのみ表示できる（二回目は表示されない）

#### シンボル => 文字列の自動変換
Railsではシンボルをテンプレート（.html.erb）内に表示しようとすると、文字列に自動変換する
e.g. :success => "success"

## 7.5 プロのデプロイ
### ポイント
#### WebサーバPumaの導入
- `config/environments/production.rb`の`config.force_ssl = true`をコメントインすると、本番環境でのSSL化が有効になる
- Rails4.2までは`config/puma.rb`の手動作成が必要だったが、Rails5以降はデフォルトで作成済み
- Procfileをプロジェクトルートに作成してherokuにgit pushすれば反映される

./Procfile

```
web: bundle exec puma -C config/puma.rb
```