RailsTutorial 7章 メモ

#7章　ユーザ登録

##デバッグとRails環境
Railsには**テスト環境**、**開発環境**、**本番環境**がある。

開発環境にデバッグ表示させるコード

```erb:デバッグ表示コード
<%= debug(params) if Rails.env.development? %>
```

コンソールでuserの情報を表示

```ruby:user情報を表示
user = User.first
puts user.attributes.to_yaml   #または
y user.attributes
```

##Usersリソース
###RESTアーキテクチャ
[詳しくはkidach1さんがまとめてくれている](https://qiita.com/kidach1/items/43e53811c12351915278)

とりあえず、下記の一文をroutes.rbに追加するだけで、Usersリソースで必要となる全てのアクションを利用できるようになる。

```ruby:Usersリソースをroutesに追加
resources :users
```

###debuggerメソッド
byebug gemによるメソッド。
コントローラ内に`debugger`を差し込むことで、コンソールにて`debugger`が呼び出された瞬間の状態を確認できる。

###ユーザ登録フォーム
ユーザ新規登録時の順序
1. /sign_upにアクセス　　@userがコントローラ上で作成される
2. ユーザが必要項目を入力
3. 登録ボタンを押す　　　 POSTでcreateアクションが実行される
4.登録完了または失敗

###Strong Parameters
createアクションにてparamsハッシュ全体を初期化するという行為はセキュリティ上、危険。
もしUserモデルに管理者かどうかを決めるadmin属性が存在した場合、`params[:user]`に`admin='1'`などの値を紛れ込ませることが可能となる。つまり、ユーザの新規作成に意図しない属性に値を保存させられる危険がある。

```ruby:危険な例
user = User.new(params[:user])
```

その問題を回避するためには、下記のようにcreateコントローラ内で保存する属性を制限してやる必要がある。

```ruby:StrongParametersで保存する属性を制限

  def create
    @user = User.new(user_params)                                               #user_paramsで保存する属性を制限
    if @user.save
      # 保存の成功をここで扱う。
    else
      render 'new'
    end
  end

  private                                                                       

    def user_params                                                             #登録時のuserの属性を制限
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)                      #name, email, password, password_confirmationのみを許可
    end
```

###エラーメッセージ
複数のビューで利用するパーシャルはapp/views/sharedのディレクトリに置くのがRails全般の慣習。
エラーメッセージの表示は他のビューでも利用するパーシャルとなるのでshared内に_error_messages.html.erbを作成。

また１つのエラーがある時は"1 error", ２つ以上のエラーがあるとき"2 errors"という風に単数形と複数形を表示で使い分けたい。
そういう場合に利用されるpluralize関数である。

```erb:数によって正しい単数形と複数形を返すpluralize関数利用例
<%= pluralize(@user.errors.count, "error") %>
```

##ユーザ登録成功
下記の２つのコードは等価です。
Railsがエンジニアのやりたいであろうことを推察して変換してくれる。

```ruby:ユーザ登録成功時にユーザページにリダイレクト
redirect_to user_url(@user)
```

```ruby:短縮版ユーザ登録成功時にユーザページにリダイレクト
redirect_to @user
```
##flash
リダイレクトした直後のページのみにメッセージを表示したい場合、**flash**という特殊な変数を使う。

```ruby:flash利用例(リダイレクト直後のみにメッセージを表示)
flash[:success] = "Welcome to the Sample App!"
redirect_to @user
```

Bootstrap CSSではflashのクラスに下記の４つのスタイルを持っている

- success
- info
- warning
- danger

###実際のユーザ登録


```ruby:データベースの内容をリセット
$ rails db:migrate:reset
```

##プロのデプロイ
###本番環境でのSSL
今のままのユーザ登録フォームでは登録ボタンを押すと、名前やメールアドレスやパスワード等のデータがネットワーク越しに流れていく。
そのデータは流れる途中で補足可能なので危険。
本番の環境では、SSLを導入してネットワークに流れる前に暗号化する必要がある。

```ruby:config/environments/production.rb
Rails.application.configure do
  .
  .
  .
  # Force all access to the app over SSL, use Strict-Transport-Security,
  # and use secure cookies.
  config.force_ssl = true
  .
  .
  .
end
```

これを行った後、遠隔にあるサーバーのSSLをセットアップし、本番用のWebサイトでSSLを使えるようにするためには、ドメイン毎にSSL証明書を購入し、セットアップする必要があります。

RailsTutorialではHerokuのサブドメインとして作っているのでHerokuのSSL証明書に便乗できる。

##本番環境用のWebサーバー
HerokuのデフォルトではWEBrickというサーバを利用しているが、沢山のトラフィックを捌くのに適していない。
そこでWEBrickからPumaというWebサーバに置き換える。

1.　puma gem をGemfileに追加（Rails 5 ではデフォルトで入っている）

2.　本番環境のWebサーバ設定ファイルを書き換え(下記スクリプト)

```ruby:config/puma.rb
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 5)
threads threads_count, threads_count

preload_app!

rackup      DefaultRackup
port        ENV['PORT']     || 3000
environment ENV['RACK_ENV'] || 'development'

on_worker_boot do
  # Worker specific setup for Rails 4.1+
  # See: https://devcenter.heroku.com/articles/
  # deploying-rails-applications-with-the-puma-web-server#on-worker-boot
  ActiveRecord::Base.establish_connection
end
```

3.　Heroku上でPumaのプロセスを走らせる設定ファイルを作成

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

###本番環境へのデプロイ

```console:コンソール上でデプロイ
$ rails test
$ git add -A
$ git commit -m "Use SSL and the Puma webserver in production"
$ git push
$ git push heroku
$ heroku run rails db:migrate
```