3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Ruby on Rails Tutorial 7章 メモ

Last updated at Posted at 2018-04-21

基本用語

サイドバー

Webサイトのページ上で、コンテンツエリアとは区別して作られたエリアのこと。

文法

Sassのミックスイン

ミックスイン機能を使うことで、CSSルールのグループをパッケージ化して複数の要素に適用することができる。

app/assets/stylesheets/custom.scss
@import "bootstrap-sprockets";
@import "bootstrap";

/* mixins, variables, etc. */

$gray-medium-light: #eaeaea;

@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; /* ミックスイン */
}

asideタグ

このタグはサイドバーなどの補完コンテンツの表示に使われるが、単独で表示することもできる。

app/views/users/show.html.erb
<% provide(:title, @user.name) %>
<div class="row">
  <aside class="col-md-4">
    <section class="user_info">
      <h1>
        <%= gravatar_for @user %>
        <%= @user.name %>
      </h1>
    </section>
  </aside>
</div>

mkdirコマンド

新しくディレクトリを作成する。

 mkdir app/views/shared

データベースの内容をリセット

rails db:migrate:reset

content_tagメソッド

タグを動的に生成する。
HTMLとERBが混ざってしまう場合などに使用するとすっきり表現できる。

# HTMLとERBが混ざってしまって読みづらい
<% flash.each do |message_type, message| %>
  <div class="alert alert-<%= message_type %>"><%= message %></div>
<% end %>

# content_tagメソッドで読みやすいコードにする
<% flash.each do |message_type, message| %>
  <%= content_tag(:div, message, class: "alert alert-#{message_type}") %>
<% end %>

環境の使い分け

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

env

RailsにはRailsというオブジェクトがあり、それには環境の論理値 (boolean) を取るenvという属性がある。

 rails console
  Loading development environment
  >> Rails.env
  => "development"
  >> Rails.env.development?
  => true
  >> Rails.env.test?
  => false

rails console

テスト環境でRails consoleを実行する。

 rails console test
  Loading test environment
  >> Rails.env
  => "test"
  >> Rails.env.test?
  => true

rails server

本番環境でRailsサーバーを実行する。

 rails server --environment production

rails db:migrate

rails db:migrateを本番環境で実行して本番データベースを作成する。

 rails db:migrate RAILS_ENV=production

Heroku

サンプルアプリケーションを既にHeroku上にデプロイしている場合は、heroku run rails consoleというコマンドを打つことで、本番環境を確認することができる。
当然ながら、Herokuは本番サイト用のプラットフォームなので、実行されるアプリケーションはすべて本番環境となる。

 heroku run rails console
  >> Rails.env
  => "production"
  >> Rails.env.production?
  => true

デバッグ出力

app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  .
  .
  .
  <body>
    <%= render 'layouts/header' %>
    <div class="container">
      <%= yield %>
      <%= render 'layouts/footer' %>
      <%= debug(params) if Rails.env.development? %> # サイトのレイアウトにデバッグ情報を追加する
    </div>
  </body>
</html>

debugメソッド

変数の値や、パラメーターの値を表示することができる。

<%= debug(params) %>

params

Railsでは、リクエスト情報をひとまとめにして、params[:パラメータ名]という形式で取得できる。
リクエスト情報で代表的なものは以下の2つ。

  • POSTでフォームから送信されたデータ
  • クエリ情報

paramsの例

class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])
  end

  def new
  end
end

ユーザーのid読み出しにはparamsを使う。
Usersコントローラにリクエストが正常に送信されると、params[:id]の部分はユーザーidの1に置き換わる。
つまり、この箇所はUser.find(1)と同じになる(params[:id]は文字列型の "1" だが、findメソッドでは自動的に整数型に変換される)。

/users/1 にアクセスすると、デバッグ情報からparams[:id]の値を確認できる。

----- 
action: show
controller: users
id: '1'

このid: ’1’は /users/:id から取得した値。
この値を使ってid=1のユーザーを検索できる、といった仕組みになっている。

User.find(params[:id])

YAML

---
controller: static_pages
action: home

デバッグ出力で表示されたこのコードは、paramsに含まれている内容で、YAMLという形式で書かれている。
YAMLは基本的にハッシュであり、コントローラとページのアクションを一意に指定する。

debuggerメソッド

byebug gemによるdebuggerメソッドを使うことで、直接的にデバッグすることが出来る。

app/controllers/users_controller.rb
class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])
    debugger # debuggerメソッド
  end

  def new
  end
end

ブラウザから /users/1 にアクセスし、Railsサーバーを立ち上げたターミナルを見ると、byebugプロンプトが表示されている。
このプロンプトではRailsコンソールのようにコマンドを呼び出すことができて、アプリケーションのdebuggerが呼び出された瞬間の状態を確認することができる。

(byebug) @user.name
"Example User"
(byebug) @user.email
"example@railstutorial.org"
(byebug) params[:id]
"1"

Railsアプリケーションの中でよく分からない挙動があったら、上のようにdebuggerを差し込んで調べてみよう。
トラブルが起こっていそうなコードの近くに差し込むのがコツ。
byebug gemを使ってシステムの状態を調査することは、アプリケーション内のエラーを追跡したりデバッグするときに非常に強力なツールになる。

RailsのREST機能

Railsアプリケーションで好まれているRESTアーキテクチャの習慣に従う。
これは、データの作成、表示、更新、削除をリソース(Resources)として扱うということ。
RESTの原則に従う場合、リソースへの参照はリソース名とユニークなIDを使う。
ユーザーをリソースとみなす場合、id=1のユーザーを参照するということは、/users/1というURLに対してGETリクエストを発行するということを意味する。
ここでshowというアクションの種類は、暗黙のリクエストになる。
RailsのREST機能が有効になっていると、GETリクエストは自動的にshowアクションとして扱われる。

RailsのREST機能を有効にする

リソース(ここではUsersリソース)をroutesファイルに追加する。

config/routes.rb
Rails.application.routes.draw do
  root 'static_pages#home'
  get  '/help',    to: 'static_pages#help'
  get  '/about',   to: 'static_pages#about'
  get  '/contact', to: 'static_pages#contact'
  get  '/signup',  to: 'users#new'
  resources :users # RailsのREST機能を有効にする
end

resources :usersという行は、ユーザー情報を表示するURL (/users/1) を追加するためだけのものではない。
サンプルアプリケーションにこの1行を追加すると、ユーザーのURLを生成するための多数の名前付きルートと共に、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) ユーザーを削除するアクション

Usersリソースが提供するRESTfulなルート

Gravatar

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

hexdigestメソッド

GravatarのURLはユーザーのメールアドレスをMD5という仕組みでハッシュ化している。
Rubyでは、Digestライブラリのhexdigestメソッドを使うと、MD5のハッシュ化が実現できる。

>> email = "MHARTL@example.COM"
>> Digest::MD5::hexdigest(email.downcase)
=> "1fda4469bcbec3badf5418269ffc5968"

メールアドレスは大文字と小文字を区別しないが、MD5ハッシュでは大文字と小文字が区別されるので、Rubyのdowncaseメソッドを使ってhexdigestの引数を小文字に変換している。

gravatar_forヘルパーメソッド

app/views/users/show.html.erb
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
app/views/users/show.html.erb
<% provide(:title, @user.name) %>
<h1>
  <%= gravatar_for @user %>
  <%= @user.name %>
</h1>

画像のサイズを指定する

app/helpers/users_helper.rb
module UsersHelper

  # 引数で与えられたユーザーのGravatar画像を返す
  # オプション引数
  def gravatar_for(user, options = { size: 80 })
    gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
    size = options[:size]
    gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}"
    image_tag(gravatar_url, alt: user.name, class: "gravatar")
  end
  
  # キーワード引数でも可
  # def gravatar_for(user, size: 80)
    # gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
    # gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}"
    # image_tag(gravatar_url, alt: user.name, class: "gravatar")
  # end
end

ユーザー登録フォーム

app/controllers/users_controller.rb
class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])
  end

  def new
    @user = User.new
  end
end

form_forヘルパーメソッド

このメソッドは、Active Recordのオブジェクトを取り込み、そのオブジェクトの属性を使ってフォームを構築する。

app/views/users/new.html.erb
<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>

<div class="row">
  <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 %>
  </div>
</div>

フォームHTML

<%= form_for(@user) do |f| %>
  .
  .
  .
<% end %>

doキーワードは、 form_forが1つの変数を持つブロックを取ることを表す。
この変数fは “form” のf。
このfオブジェクトは、HTMLフォーム要素 (テキストフィールド、ラジオボタン、パスワードフィールドなど) に対応するメソッドが呼び出されると、@userの属性を設定するために特別に設計されたHTMLを返す。
つまり、次のコードを実行すると、

<%= f.label :name %>
<%= f.text_field :name %>

Userモデルのname属性を設定する、ラベル付きテキストフィールド要素を作成するのに必要なHTMLを作成する。

# 埋め込みRuby
<%= form_for(@user) do |f| %>
  .
  .
  .
<% end %>

# 生成されたHTML
<form accept-charset="UTF-8" action="/users" class="new_user"
      id="new_user" method="post">
  .
  .
  .
</form>

Railsはformタグを作成するときに@userオブジェクトを使う。
すべてのRubyオブジェクトは自分のクラスを知っているので、Railsは@userのクラスがUserであることを認識する。
また、@userは新しいユーザーなので、Railsはpostメソッドを使ってフォームを構築すべきだと判断する。
なお、新しいオブジェクトを作成するために必要なHTTPリクエストはPOSTなので、このメソッドはRESTfulアーキテクチャとして正しいリクエストになる。
action="/users"とmethod="post"の2つの属性では、/users に対してHTTPのPOSTリクエスト送信する、といった指示をしている。

# 埋め込みRuby
<%= f.label :name %>
<%= f.text_field :name %>

# 生成されたHTML
<label for="user_name">Name</label>
<input id="user_name" name="user[name]" type="text" />

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

# 埋め込みRuby
<%= f.label :email %>
<%= f.email_field :email %>

# 生成されたHTML
<label for="user_email">Email</label>
<input id="user_email" name="user[email]" type="email" />
# 埋め込みRuby
<%= f.label :password %>
<%= f.password_field :password %>

# 生成されたHTML
<label for="user_password">Password</label>
<input id="user_password" name="user[password]" type="password" />

テキストフィールド (type="text"とtype="email") では内容をそのまま表示しているが、パスワードフィールド (type="password") ではセキュリティ上の目的のために文字が隠蔽されている。
(emailフィールドとtextフィールドは同じように見えるが、細かな点が違う。例えばtype="email"となっている場合、モバイル端末から入力フォームをタップすると、メールアドレスに最適化された特別なキーボードが表示されるようになる。)

<input name="utf8" type="hidden" value="&#x2713;" />
<input name="authenticity_token" type="hidden"
       value="NNb6+J/j46LcrgYUC60wQ2titMuJQ5lLqyAbnbAUkdo=" />

formタグの内側で生成されたこのHTMLはブラウザ上では何も表示しませんが、Railsの内部で使われる特別なコード。
Unicode文字の「&#x2713; (チェックマーク ✓)」を使ってブラウザが正しい文字コードを送信できるようにしたり、Cross-Site Request Forgery(CSRF)と呼ばれる攻撃を阻止するために信頼できるトークンを含めたりしている。

Strong Parameters

次のようなコードは、paramsハッシュ全体を初期化するため、セキュリティ上極めて危険になっている。
これは、ユーザーが送信したデータをまるごとUser.newに渡していることになるから。
Userモデルにadmin属性というものがあるとしたとき、admin=’1’という値をparams[:user]の一部に紛れ込ませて渡してしまえば、この属性をtrueにすることができる。
これはcurlなどのコマンドを使えば簡単に実現できる。
paramsハッシュがまるごとUser.newに渡されてしまうと、どのユーザーでもadmin=’1’をWebリクエストに紛れ込ませるだけでWebサイトの管理者権限を奪い取ることができる。
こういった理由から、Rails 4.0以降では、エラーとすることでセキュリティを高め、Strong Parametersと呼ばれるテクニックで対策することを標準とした。

app/controllers/users_controller.rb
class UsersController < ApplicationController
  .
  .
  .
  def create
    @user = User.new(params[:user])    # ダメな例
    if @user.save
      # 保存の成功をここで扱う。
    else
      render 'new'
    end
  end
end

Strong Parametersの例

Strong Parametersを使うことで、必須のパラメータと許可されたパラメータを指定することができる。
さらに、上のようにparamsハッシュをまるごと渡すとエラーが発生するので、Railsはデフォルトでマスアサインメントの脆弱性から守られるようになった。

app/controllers/users_controller.rb
class UsersController < ApplicationController
  .
  .
  .
  def create
    @user = User.new(user_params)
    if @user.save
      # 保存の成功をここで扱う。
    else
      render 'new'
    end
  end

  private # Rubyのprivateキーワードを使って外部から使えないようにする

    def user_params # privateキーワードを使うことで、user_paramsメソッドはUsersコントローラの内部でのみ実行され、Web経由で外部ユーザーにさらされない
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)
    end
end

privateキーワード

Rubyのprivateキーワードを使って外部から使えないようにする。
privateキーワード内のメソッドは、Usersコントローラの内部でのみ実行され、Web経由で外部ユーザーにさらされない
また、privateキーワード以降のコードを強調するために、user_paramsのインデントを1段深くする。

user_paramsメソッド

paramsハッシュでは:user属性を必須とし、名前、メールアドレス、パスワード、パスワードの確認の属性をそれぞれ許可し、それ以外を許可しないようにする。
このコードの戻り値は、paramsハッシュのバージョンと、許可された属性 (:user属性がない場合はエラーになる)。

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

エラーメッセージを表示させる

保存に失敗すると、@userオブジェクトに関連付けられたエラーメッセージの一覧が生成される。
このメッセージをブラウザで表示するには、ユーザーのnewページでエラーメッセージのパーシャル (partial) を出力する。
このとき、form-controlというCSSクラスも一緒に追加することで、Bootstrapがうまく取り扱ってくれるようになる。
また、Rails全般の慣習として、複数のビューで使われるパーシャルは専用のディレクトリ「shared」によく置かれる。

app/views/users/new.html.erb
<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_for(@user) do |f| %>
      <%= render 'shared/error_messages' %> # エラーメッセージを表示させる

      <%= f.label :name %>
      <%= f.text_field :name, class: 'form-control' %> # form-controlクラスを追加

      <%= f.label :email %>
      <%= f.email_field :email, class: 'form-control' %> # form-controlクラスを追加

      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %> # form-controlクラスを追加

      <%= f.label :password_confirmation, "Confirmation" %>
      <%= f.password_field :password_confirmation, class: 'form-control' %> # form-controlクラスを追加

      <%= f.submit "Create my account", class: "btn btn-primary" %>
    <% end %>
  </div>
</div>

ディレクトリ(app/views/shared)を作成する。

 mkdir app/views/shared

パーシャル(_error_messages.html.erb)を作成する。

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

countメソッド

これはエラーの数を返す。

>> user.errors.count
=> 2

any?メソッド

any?メソッドはちょうどempty?と逆の動作で、要素が1つでもある場合はtrue、ない場合はfalseを返す。

>> user.errors.empty?
=> false
>> user.errors.any?
=> true

pluralize

pluralizeの最初の引数に整数が与えられると、それに基づいて2番目の引数の英単語を複数形に変更したものを返す。
このメソッドの背後には強力なインフレクター(活用形生成)があり、不規則活用を含むさまざまな単語を複数形にすることができる。

>> helper.pluralize(1, "error")
=> "1 error"
>> helper.pluralize(5, "error")
=> "5 errors"
<%= pluralize(@user.errors.count, "error") %>

このコードは、例えば "0 errors"、"1 error"、"2 errors" などのように、エラーの数に応じて活用された単語を返す。
これにより、"1 errors" のような英語の文法に合わない文字列を避けることができる。

エラーメッセージにスタイルを与える

Sassの@extend関数

@extend関数: スタイルを継承する
ここでは、Sassの@extend関数を使ってBootstrapのhas-errorというCSSクラスを適用している。
@extend関数の注意点

app/assets/stylesheets/custom.scss
.
.
.
/* forms */
.
.
.
#error_explanation {
  color: red;
  ul {
    color: red;
    margin: 0 0 30px 0;
  }
}

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

無効なユーザー登録に対するテスト

require 'test_helper'

class UsersSignupTest < ActionDispatch::IntegrationTest

  test "invalid signup information" do
    get signup_path
    assert_no_difference 'User.count' do
      post users_path, params: { user: { name:  "",
                                         email: "user@invalid",
                                         password:              "foo",
                                         password_confirmation: "bar" } }
    end
    assert_template 'users/new' # 送信に失敗したときにnewアクションが再描画されるはずなので、assert_templateを使ったテストも含めている
  end
end

assert_no_differenceメソッド

ブロックで渡されたものを呼び出す前と呼び出した後で違いがないと主張する。

assert_no_difference 'User.count' do
  post users_path, params: { user: { name:  "",
                                     email: "user@invalid",
                                     password:              "foo",
                                     password_confirmation: "bar" } }
end

次のコードは等価ではあるが、assert_no_differenceを使う方が明瞭で、Rubyの慣習的にも正しい。

before_count = User.count
post users_path, ...
after_count  = User.count
assert_equal before_count, after_count

登録フォームの完成

redirect_to メソッド

指定されたページにリダイレクトする。

app/controllers/users_controller.rb
class UsersController < ApplicationController
  .
  .
  .
  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to @user # ユーザーのページにリダイレクトする
    else
      render 'new'
    end
  end
  .
  .
  .

また、redirect_to @userというコードから (Railsエンジニアが) user_url(@user)といったコードを実行したいということを、Railsが推察してくれる。

redirect_to @user

# 上のコードと等価
redirect_to user_url(@user)

flash

登録完了後に表示されるページにメッセージを表示し (この場合は新規ユーザーへのウェルカムメッセージ)、2度目以降にはそのページにメッセージを表示しないようにする。
flashという特殊な変数はハッシュのように扱う。
Railsの一般的な慣習に倣って、:successというキーには成功時のメッセージを代入する。
また、Bootstrap CSSは、このようなflashのクラス用に4つのスタイルを持っている (success、info、warning、danger)。

app/controllers/users_controller.rb
class UsersController < ApplicationController
  .
  .
  .
  def create
    @user = User.new(user_params)
    if @user.save
      flash[:success] = "Welcome to the Sample App!"
      redirect_to @user
    else
      render 'new'
    end
  end
  .
  .
  .

flash変数に代入したメッセージは、リダイレクトした直後のページで表示できるようになる。
flash内に存在するキーがあるかを調べ、もしあればその値 (メッセージ) を全て表示するように、レイアウトを修正する。
flash変数の内容をWebサイト全体にわたって表示できるようにすると、次のようなコードになる。

app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  .
  .
  .
  <body>
    <%= render 'layouts/header' %>
    <div class="container">
      <% flash.each do |message_type, message| %> # flash
        <div class="alert alert-<%= message_type %>"><%= message %></div>
          # 読みやすくしたコード
          <%#= content_tag(:div, message, class: "alert alert-#{message_type}") %>
      <% end %> 
      <%= yield %>
      <%= render 'layouts/footer' %>
      <%= debug(params) if Rails.env.development? %>
    </div>
    .
    .
    .
  </body>
</html>

適用するCSSクラスをメッセージの種類によって変更するようにしている。

alert-<%= message_type %>

# :successキーのメッセージが表示される場合
alert-success

このとき、:successキーはシンボルだったが、テンプレート内に反映させる際に埋め込みRubyが自動的に"success"という文字列に変換している。
この性質を利用することで、キーの内容によって異なったCSSクラスを適用させることができ、メッセージの種類によってスタイルを動的に変更させることができる。

有効なユーザー登録に対するテスト

test/integration/users_signup_test.rb
require 'test_helper'

class UsersSignupTest < ActionDispatch::IntegrationTest
  .
  .
  .
  test "valid signup information" do
    get signup_path
    assert_difference 'User.count', 1 do
      post users_path, params: { user: { name:  "Example User",
                                         email: "user@example.com",
                                         password:              "password",
                                         password_confirmation: "password" } }
    end
    follow_redirect!
    assert_template 'users/show'
  end
end

上のコードでは、ユーザープロフィールに関するほぼ全て (例えばページにアクセスしたらなんらかの理由でエラーが発生しないかどうかなど) をテストできている。
この類のエンドツーエンドテストは、アプリケーションの重要な機能をカバーしてくれている。
統合テストが便利だと呼ばれる所以はこういった理由にある。

assert_differenceメソッド

このメソッドは第一引数に文字列 (’User.count’) を取り、assert_differenceブロック内の処理を実行する直前と、実行した直後のUser.countの値を比較する。
第二引数はオプションだが、ここには比較した結果の差異 (今回の場合は1) を渡す。

follow_redirect!メソッド

このメソッドは、POSTリクエストを送信した結果を見て、指定されたリダイレクト先に移動するメソッド。
したがって、この行の直後では’users/show’テンプレートが表示されているはず。

プロのデプロイ

本番環境でのSSL

ユーザー登録フォームで送信すると、名前やメールアドレス、パスワードといったデータがネットワーク越しに流されていく。
実は、このようなネットワークに流れるデータは途中で捕捉できるため、扱いには注意が必要。そしてこれを修正するためにSecure Sockets Layer(SSL)を使う。
これはローカルのサーバからネットワークに流れる前に、大事な情報を暗号化する技術。

SSLを有効化する

本番環境では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

遠隔にあるサーバーのSSLをセットアップする

本番用のWebサイトでSSLを使えるようにするためには、ドメイン毎にSSL証明書を購入し、セットアップする必要がある。
これには多くの作業が必要となるが、幸運にもそういった作業をしなくても済む方法がある。
それは、Heroku上でサンプルアプリケーションを動かし、HerokuのSSL証明書に便乗する方法 (ただし、この方法はHerokuのサブドメインでのみ有効。独自ドメインを使う場合はSSL証明書を購入する必要がある)。

本番環境用のWebサーバー

Herokuのデフォルトでは、Rubyだけで実装されたWEBrickというWebサーバを使っている。
WEBrickは簡単にセットアップできたり動せることが特長だが、著しいトラフィックを扱うことには適していない。
つまり、WEBrickは本番環境として適切なWebサーバではない。
よって、今回はWEBrickをPumaというWebサーバに置き換えてみる。
Pumaは多数のリクエストを捌くことに適したWebサーバ。

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"を作成し、Pumaを使えるように定義する。

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

参考文献

[Web担当者Forum]
(https://webtan.impress.co.jp/g/%E3%82%B5%E3%82%A4%E3%83%89%E3%83%90%E3%83%BC)
content_tag - リファレンス - - Railsドキュメント
Railsでparamsを使ってデータを取得する
Railsでデバッグをする
@extendを使うべき時、@mixinを使うべき時

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?