Rails Tutorial（2週目）-7-

#3つの環境
>Railsにはテスト環境 (test)、開発環境 (development)、そして本番環境 (production) の3つの環境がデフォルトで装備されています。Rails consoleのデフォルトの環境はdevelopmentです。

`$rails console test`でtest環境のコンソール立ち上げ
`$rails server --environment production`rails serverを開発環境で立ち上げ
`$rails db:migrate RAILS_ENV=prodction` で本番データーベースの作成

#Sassのmixinとextend
##mixin
>何度も使うスタイルを定義することが出来、引数が使える。呼び出し時には@includeが必要

```
@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;
}
```

###extend
既に定義しているスタイルを継承する。クラスの継承に近い感覚。
コンパイル後、セレクタがグループ化される。(以下「Sass(SCSS)のmixin, extendなどまとめ」より引用（https://qiita.com/one-a/items/2758511326c09200fded)

```
.box {
  margin-top: 15px;
  padding: 10px;
  background-color: #ccc;

  p {
    line-height: 1.3;
  }
}

.contentsBox {
  @extend .box;
  background-color: #eee;
}

```
次のようにCSSファイルに変換される

```
.box, .contentsBox {
  margin-top: 15px;
  padding: 10px;
  background-color: #ccc;
}

.box p, .contentsBox p {
  line-height: 1.3;
}

.contentsBox {
  background-color: #eee;
}
```
.box, .contentsBoxのように同一の要素がグループ化されているのがわかる。
Usersリソース
route.rbに`resources :users`と記述することでRESTfulなUsersリソースで必要となる全てのアクションが利用できるようになる。また、この行に対応するURLやアクション、名前付きルートは以下のようになる。

| 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) | ユーザーを削除するアクション |

#byebug
byebugというgemをインストールしていると、
メソッド内にdebuggerと記述するだけで、対話的にデバッグの処理を行う事ができる。

#Gravatar
>Gravatarは無料のサービスで、プロフィール写真をアップロードして、指定したメールアドレスと関連付けることができます。その結果、 Gravatarはプロフィール写真をアップロードするときの面倒な作業や写真が欠けるトラブル、また、画像の置き場所の悩みを解決します。というのも、ユーザーのメールアドレスを組み込んだGravatar専用の画像パスを構成するだけで、対応するGravatarの画像が自動的に表示されるからです

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

#ユーザー登録フォームの作成
Railsでform_forヘルパーメソッドを使います。このメソッドはActive Recordのオブジェクトを取り込み、そのオブジェクトの属性を使ってフォームを構築します。

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

***form_for(@user) do |f|***となっている部分は、form_forヘルパが、変数を一つ持つブロックを引数に取り、そのブロック変数はHTMLのフォーム要素に対応するメソッドが自身に呼び出されると、form_forの引数となっているユーザーの属性を設定するために特別に設計されたHTMLを返す。

HTMLに変換後のコードを見てみると
`<input id="user_name" name="user[name]" - - - />
.
.
.
<input id="user_password" name="user[password]" - - - />`

inputには属性として代表的なものに、 name属性,value属性、type属性などがある。
##name属性
>入力コントロールの名前を指定する文字列です。この名前は <form> 要素の elements オブジェクトで保持され、フォームデータが送信される時に、コントロールの値と共に送信されます。

Railsにおいては、Railsはnameの値を使って、初期化したハッシュを (params変数経由で) 構成します。このハッシュは、入力された値に基づいてユーザーを作成するときに使われます。

つまり、user = {password: ##, email: ## ....}というuserを表すハッシュが存在し、params内に格納されるが、name属性を指定するとそのうち、passwordをキーとするuserハッシュの要素（入力された内容）がparamsに格納される。

この結果、name,email,password,password_confirmationで構成されるuserという名前のハッシュが、paramsというハッシュの中に格納される。

##formタグ
`<form action="/users" class="new_user" id="new_user" method="post">
`　action属性はフォーム経由で送信された情報を処理するプログラムの URI。method属性は、HTTPメソッドの指定。

#本格的なユーザー登録
paramsの送信先のcreateアクション内で
`@user = User.new(params[:user])  `とすることで、フォーム内容に対応したユーザの作成が可能だが、paramsハッシュ全体を初期化してUser.newにわたすのは危険

>以前のバージョンのRailsでは、モデル層でattr_accessibleメソッドを使うことで上のような危険を防止していましたが、Rails 4.0ではコントローラ層でStrong Parametersというテクニックを使うことが推奨されています。Strong Parametersを使うことで、必須のパラメータと許可されたパラメータを指定することができます。さらに、上のようにparamsハッシュをまるごと渡すとエラーが発生するので、Railsはデフォルトでマスアサインメントの脆弱性から守られるようになりました。

`params.require(:user).permit(:name, :email, :password, :password_confirmation)`
上のコードはparamsハッシュのうち、:user属性を必須として、そのうち名前、メールアドレス、パスワード、パスワードの確認の属性をそれぞれ許可し、それ以外を許可しないようにしてある。
このコードの戻り値は、許可された属性のみが含まれたparamsのハッシュです (:user属性がない場合はエラーになります)。

これらのパラメータを利用しやすくするために、user_paramsという外部メソッドを使うのが慣習化している。

#エラーメッセージ
newページでエラーメッセージのパーシャルを出力する
`<%= render 'shared/error_messages' %>`
Rails全般の慣習として、複数のビューで使われるパーシャルは専用のディレクトリ「shared」によく置かれる

```app/views/shared/_error_messages.html.erb
<% if @user.errors.any? %>
  <div id="error_explanation">
    <div class="alert alert-danger">
      The form contains <%= pluralize(@user.errors.count, "error") %>.
    </div>
    <ul>
    <% @user.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
<% end %>
```

##pluralizeヘルパ
pluralizeの最初の引数に整数が与えられると、それに基づいて2番目の引数の英単語を複数形に変更したものを返します。
`>> helper.pluralize(1, "error")
=> "1 error"`

Railsは、無効な内容の送信によって元のページに戻されると、CSSクラスfield_with_errorsを持ったdivタグでエラー箇所を自動的に囲んでくれます。

##エラーメッセージの重複を防ぐ
allow_ nil: true　で防げる

#ユーザー登録成功
`def create
    @user = User.new(user_params)
    if @user.save
      redirect_to @user
    else
      render 'new'
    end
  end`

`redirect_to @user`は
`redirect_to user_url(@user)`と等価（Railsが自動で変換してくれる）

#flash
>登録完了後に表示されるページにメッセージを表示し (この場合は新規ユーザーへのウェルカムメッセージ)、2度目以降にはそのページにメッセージを表示しないようにするというものです。

flashはハッシュのように扱う特殊な変数
flash変数に代入したメッセージは、リダイレクトした直後のページで表示できるようになります。

（例）`flash[:success} = "welcome"`

#SSL
ローカルのサーバからネットワークに流れる前に、大事な情報を暗号化する技術。
ユーザーから送られた情報を暗号化することで、セキュリティ上の欠陥をなくす。
##SSLの有効化
production.rbという本番環境の設定ファイルにsslを使用するように記述する

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

#WEBサーバーをWEBrickからPumaに変える
WEBrickは簡単にセットアップできたり動せることが特長ですが、著しいトラフィックを扱うことには適していない。

・puma gemをGemfileに追加する（rails5ではデフォルトの設定で使える）
・設定を書き込んでいく

```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
```
・Procfileと呼ばれる、Heroku上でPumaのプロセスを走らせる設定ファイルを作成

```./Procfile(ルートディレクトリ）
web: bundle exec puma -C config/puma.rb
```

#本番環境へのデプロイ

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