Rails – パスワードの暗号化~ゼロから

概要

パスワードをデータベースに保存する際に暗号化して、万一流出した際のリスクを減らす方法。ここではハッシュ化してメッセージダイジェストにすることを「暗号化」とする。

暗号化されたパスワードを保存しておき、サインインの際に入力されたパスワードを同じ手順で暗号化し、得られたメッセージダイジェストが一致すれば符合しているとする。

以下の方法で順次リスクを減らしていく。

  1. パスワードをハッシュ化
  2. パスワードにソルトを連結してハッシュ化
  3. パスワードとソルトをそれぞれハッシュ化したものを連結してハッシュ化
  4. より安全性の高いハッシュ化を適用

ここでは3つ目の方法でRailsのDigest::MD5を使った手順を整理。

手順

パスワードを与える。

password = "pass"

ソルトを準備する。

salt = "SdvLigVDW3iDtHGAYvccBSbDn+jl"

パスワードとソルトを連結した文字列を暗号化する。

Digest::MD5.hexdigest(pass_digest + salt_digest)

この結果、以下のメッセージダイジェストが得られる。

"d1d7bd4a8d1e0a3be09d701db50ec038"

パスワードをpass→sassにしたときのメッセージダイジェストは以下の通り。

"82035cbcc496621133b8773709285313"

モデルへの実装

Railsでモデルを介してデータベースに登録する場合、モデルに暗号化の処理を書く。たとえばUserモデルのpasswordを暗号化する場合の例は以下の通り。

before_createでコールバックを設定していて、データベースへの書き込み前にencrypt_passwordメソッドが呼ばれる。

これをbefore_saveで呼ぶとデータ更新のときにもパスワードがハッシュ化されてしまうので、データの新規作成のときだけ呼ばれるようbefore_createで呼ばなければんならない。

encrypt_passwordはクラスメソッドのpassword_digestpasswordをメッセージダイジェストに変換し、その値でpasswordを書き換える。

password_digestメソッドは、パスワードとソルトからメッセージダイジェストを返す。

その結果、データベースへの書き込み時には暗号化されたパスワードが保存される。

 

Rails – flash

概要

flashはFlashHashクラスのインスタンスで、エラーなどのメッセージを遷移後の画面に表示するときに使う。ハッシュの様に状態キーに対するメッセージを登録するが、リクエストごとにクリアされる(Railsガイド)。

たとえばエラーメッセージの表示に使う手順は以下のとおり。

  1. バリデーションや保存処理などの結果に応じて、flashをセット
    • flash[状態キー] = "メッセージ"
  2. リダイレクト後の画面でflashを参照し、状態キーに応じたメッセージを表示

基本動作

前提

たとえば以下の例ではform_with@userの名前(:name)を入力して、ユーザー名が英数6文字以内であることを要求している。

app/views/flash_test.html.erb

モデルのバリデーションで、ユーザー名の長さと構成文字の検証を行う。

  • ユーザー名は6文字以上
  • ユーザー名に使える文字は英数字のみ

app/models/user.rb

flashへの登録

通常はバリデーションはデータベースへの書き込み時に行われるが、ここではvalid?でバリデーションを強制している。

検証の結果が適正であればflashに:successのキーで「適正な入力」、不適正であれば:dangerのキーで「不適正な入力」のメッセージを登録している。

その後、結果によらず最初のページを表示するアクションへリダイレクト(リダイレクト先のページは任意だが、ここでは最初のページにしている)。

app/controllers/pages_controller.rb

flashに対応した表示

リダイレクト/レンダリング後のビューに、flashの結果に応じた表示を行うコードを追加する。

app/views/flash_test.html.erb

flashのキー・値のセットの分だけeachで取り出して表示するが、その際にキーに応じたクラスを設定している。

そのレンダリング結果を確認してみよう。

遷移前のページでの入力が適正だった場合は、コントローラーでflash:successをキーとして「適正な入力」のメッセージ文字列が渡される。このとき、キーの内容(:success)を使ってクラス設定が行われる。

一方、入力が不適正だった場合にはコントローラーでflash:dangerをキーとするメッセージが渡され、それがレンダリングされた結果は以下のとおり。

この結果、遷移前のページでのバリデーション結果に応じた表示が行われる。

スタイルの変化

動的なクラス設定に対するスタイル

先のコードで、入力の結果に応じてメッセージのクラスが動的に設定された。スタイルファイルでそれらのクラスに応じたスタイルを定義することで、結果に応じた変化をつけることができる。

以下のスタイルファイルは、flashの結果セットされたクラスに応じてメッセージの色に変化をつけている。

処理の概要は以下のとおり。

  1. flashによる通知全般のスタイル設定
    .notice
  2. flashのキー(:success/:danger)に応じてセットされたクラスによって色を変化させる
    &_success/&_danger

<実行結果>

以下はバリデーションエラーの場合で、適正な場合は「適正な入力」と表示される。

ダイアログ表示

flashの内容を遷移後のページの表示前にダイアログで表示する場合、application.html.erbhead部分にJavaScriptを記述。

app/views/layouts/application.html.erb

処理の概要は以下のとおり。

  1. headブロックでダイアログ表示のスクリプトを定義
  2. flashがセットされている場合にダイアログを表示
  3. ダイアログのメッセージに、flashのすべてのメッセージを改行で結合して表示

<実行結果>

:dangerのときだけダイアログを表示する場合は以下の様になる。

has_key?を使うため、to_hashflashをハッシュに変換している。ただし、to_hashでハッシュに変換するとキーがシンボルではなく文字列になる点に注意。

一定時間後に表示を消す

flashに応じて表示されたメッセージを一定時間後に消すには、JavaScriptを使う。application.html.erbに以下の様に書く。

app/views/layouts/application.html.erb

処理の概要は以下のとおり。

  1. 必要に応じてJQueryを読み込む
  2. bodyの最初(最上部)にメッセージ表示エリアを定義
  3. 一定時間表示させた後にスライドアップで表示を消すスクリプトを定義
    1. $(".notice").slideUp()でメッセージをスライドアップ消去
    2. 1.5秒後に消去を実行するよう、window.setTimeoutにコールバックとして渡す

なお、:success:dangerによって表示の色を変える設定をCSSに書いている。

 

<実行結果>

以下、danger/successに応じた表示で、1.5秒後にこれらの表示がスライドアップされて消去される。

 

Rails – バリデーション

概要

Railsでモデルを介してフォーム入力を扱う場合、入力データが適正かどうか条件を設定して検証できる。

検証の条件はvalidatesをモデルクラス内で定義し、savevalid?などのメソッド実行に際して検証が行われる。これらのメソッドは検証結果の適正/不適正によってtrue/falseの戻り値を持つので、その結果に応じてflashによるエラー表示などの処理を行うことができる。

バリデーションの記述

モデルクラスの定義で以下を記述。

validates:(:対象カラム , 検証内容1, 検証内容2, ...) 

たとえばUserモデルのnameの存在と長さを検証する場合は以下のように書く。

app/models/user.rb

バリデーションの確認

通常、モデル内にvalidatesを書くと、モデルのsave実行前に検証が行われる。

モデルインスタンスのvalid?を実行すると、その時点でモデルの内容が妥当かどうかが検証され、検証結果が妥当であればtrue、妥当でなければfalseが返される。

また、妥当でない場合のエラーの内容は、モデルのerrors.messagesで確認できる。

app/controllers/users_controller.rb

たとえば検証結果が妥当な場合のRailsサーバーのログは、

何も入力しなかった場合は、

長さが制限を超えた場合は、

バリデーションの種類

presence~存在確認

<書式>

presence: true

入力内容がnil、空文字列、スペースでないことを検証する。全角スペースも検証の対象となる。内部でblank?メソッドを使っている。

<実行例>

モデル

errors.messages

逆にnil、空文字列、スペースのみであることを検証する場合はabscenceを使う。

length~長さの検証

<書式>

length: { 制限オプション: 制限値 }

長さを検証する。制限オプションと制限値のパターンは以下の通り。

  • :minimum:長さの最小値
    • 例:{ minimum: 10 }
  • :maximum:長さの最大値
    • 例:{ maximum: 20 }
  • :is:長さがこの値に一致しなければならない
    • 例:{ is: 10 }
  • :in/:witnin:長さの範囲
    • 例:{ in: 10..20 }

<実行例>

モデル

errors.messages

numericality~数値の検証

<書式>

numericality: true

numericality: { 制限オプション: 制限値 }

入力内容が数値形式であることを検証する。デフォルトでは整数・実数にマッチするが、制限オプションでいろいろなパターンを検証できる。

  • :only_integer:整数
  • :even/:odd:偶数/奇数
  • :equal_to:与えた数に等しい
  • :other_than:与えた数以外
  • :greater_than:与えた数より大きい
  • :greater_than_or_equal_to:与えた数より大きい
  • :less_than:与えた数より大きい
  • :less_than_or_equal_to:与えた数より大きい

<実行例>

errors.messages

format~パターンマッチング

<書式>

format: { with: 正規表現 }

入力のパターンが正規表現にマッチするかどうか検証する。正規表現を定数に設定しておく書き方が使われる。

<実行例>

モデル

errors.messages

検証結果のメッセージ

メッセージの構造

検証結果のエラーが1つの場合の、バリデーションのメッセージを確認する。

入力値とメッセージの内容は以下の通り。

 

この出力は以下のコードで表示させている。出力結果から、errors.messagesの内容は以下のようであることがわかる。

  • errors.messagesはハッシュ
  • ハッシュの キーはモデル名
  • ハッシュの値は配列で、配列の要素はメッセージ文

これを踏まえて、以下のコードの10行目のように取り出している。

複数の検証を設定した場合

1つの要素に複数の検証を設定し、それらがエラーになった場合を考える。

errors.messagesがハッシュなので、eachでキーと値を取り出し、その値が配列なのでeachで各メッセージを取り出す。

表示結果は以下の通り。

message:~メッセージの定義

メッセージは英語の文字列だが、message:で検証項目ごとのメッセージを定義できる。たとえば上の例で長さとパターンのそれぞれにメッセージを追加した例。

実行結果は以下の通り。

presenceuniquenessの場合は以下のように定義する。

presence: { message: "未入力の場合のメッセージ" }

uniqueness: { message: "重複したの場合のメッセージ" }

 

Rails – モデルによるフォームデータの取得

 

前提

例題として以下のようなモデルを使う。

  • モデル名はuser
  • モデルのフィールドはnamepasswordの2つで、いずれもstring

手順

モデルインスタンスとフォームの準備

フォームを呼び出すコントローラーで、モデルインスタンスを準備する。

app/controllers/pages_controller

フォーム側で、そのインスタンスを引数にとる。

app/views/pages/params_check.html.erb

 

フォームデータの取得

パラメーター取得の考え方

モデルを介してフォームデータを取得する考え方は以下の通り。

  • paramsrequireメソッドでモデルを指定してパラメーターを取得
  • Railsの慣習として、上記の処理をprivateメソッドとする

params.require

以下のメソッドチェーンで、パラメーターのハッシュが得られる。

params.require(モデル名).permit(キー1, キー2, ...)

今回の例の場合は以下の通り。

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

メソッド化

コントローラーにprivateで以下のメソッドを定義。

データの利用

パラメーターが必要な場合はこのメソッドを呼び出す。たとえばフォーム入力データをコンソールに出力する例として、

以下はフォーム入力のコンソールへの出力例。

permitの意味~ストロングパラメーター

モデルに寄らないフォーム入力の場合paramsは単純なハッシュだが、モデルを介した場合は、paramsにモデル名をキーとするパラメーターのハッシュが含まれる。

今回の例の場合のparamsの内容は以下の通り。

params[:user]をキーとしたハッシュを取り出すと、フォーム入力が得られる。

そして、この結果はrequire.permitを通した結果とほぼ同じ。

 

ただし最後のpermittedが異なり、paramsの場合はfalsepermit.requireを通した場合はtrueになっている。

permitted: falseの場合はデータを一度に保存するマスアサインメントが使用できない。これを許すと、悪意のあるユーザーが不適切なデータを追加して送信し、データベースに書き込まれてしまう恐れがある。

require.permitによる場合はあらかじめ取り扱い可能なデータが限定されているので、permitted: trueに設定され、マスアサインメントが可能となる。

 

 

Rails – 掲示板 – フォーム入力の確認

概要

仮作成したページで、フォームからPOSTされたデータが取得できることを確認する。

掲示板の第1段階へ

アクションの追加

フォームからのデータはPOSTメソッドで送られてくるので、これを受信してサインアップ/サインインの処理を行うアクションをコントローラーに追加する。

ルーティング

追加したアクションに対するルーティングを設定する。

ルーティングの設定状況を確認すると、POSTメソッドに対するPrefixが設定されていない。

そこで、ルーティングにas:でPrefixを設定する。

その結果POSTメソッドのルーティングにもPrefixが設定され、Prefix_pathの定型句でのURL指定が可能になった。

フォームのURL指定

サインアップ/サインインを扱うアクションへのルーティングが決まったので、フォームのアクションを設定する。

sign_up.html.erbについては以下の通り。

sign_in.html.erbの方は以下の通り。

アクションのURL指定では、Prefix_pathの定型句を使っている。

パラメーターの確認

この状態でRailsサーバーを起動させて、サインアップページで何も入力せずにサインアップボタンを押す。

その処理結果をRailsサーバーのコンソールで確認すると、:name:email:passwordが送られてきているのがわかる(:passwprdはフィルタリングされている)。

これらの値はparams変数でキーを指定して参照することができる。PHPの$_POSTと同じように、paramsもグローバル・スコープを持っている。

ここでフォームに何か入力してサインアップボタンを押すと、以下のようにコンソールに入力内容が表示される。

params[:password]を直接表示させるとパスワードが平文で見られることに注意。

 

Rails – 掲示板 – 仮ページの作成

概要

コントローラーとビューの準備によって、プロジェクトの枠組みをつくった。

ここでは、仮置きのページとして3つのhtml.erbファイルの内容を書いていき、それらにスタイルを定義する。

掲示板の第1段階へ

ルーティング

第1段階では、それぞれのページのURLを指定して表示させる設定。

ルーティングの状況を確認する。後でヘルパーのリンク先URLを指定するとき、Prefix_pathという定型句で指定することができる。

共通レイアウト

サインアウト中ページ用

application_signed_out.html.erb

サインアウト中のページには特にヘッダーメニューなどを表示しないので、デフォルトで生成されたapplication.html.erbの内容通り。

ただしこちらを利用するのがsign_insign_upの2つのアクションだけと限定的なので、ファイル名を変更する。

users_controller.rb

デフォルトのapplication.html.erb以外を共通レイアウトとして使う場合は、コントローラーから明示的に呼び出す。

サインイン済みページ用

application.html.erb

サイン済みユーザーに対しては、第1段階ではtopページのみ表示させるが、今後いろいろな機能をつけていく。こちらの方が主になるので、ファイル名をデフォルトのapplication.html.erbとし、ヘッダーメニューを加える。

header.scss

ヘッダーに対するスタイル定義(HTML/CSSのヘッダーメニューを参照)。

個別ページ

topページ

top.html

第1段階では、仮置きとしてユーザー一覧を表示させる。

pages.scss

topページに対するスタイル定義は、topアクションを持つpagesコントローラーと同名のscssに書く。

メイン部分の領域が縦一杯に広がるようにするために、htmlbodyheightに100%を指定している。

sign_upページ・sign_inページ

sign_up.html.erb

sign_upsign_inは殆ど似たような内容・デザイン。モデルなしのform_withヘルパーを使い、URLは仮置きしている。

また、link_toヘルパーのリンク先に、ルーティングのPrefixを使った名前でURLを指定している。

sign_in.thml.erb

users.scss

sign_upsign_inの2つのビューのスタイルは、それらのアクションを持つusersコントローラーと同名のusers.scssに書く。

リセットCSS

reset.scss

リセットCSSにはEric Meyer’s “Reset CSS” 2.0を使った。

スタイルの読み込み

application.html.erbapplication_signed_out.html.erbのいずれも、最初にapplication.cssを呼び出している。その中で必要なSCSSファイルを読み込んでいる。

書くスタイルファイルが読み込まれるのは1度だけなので、最初にreset.scssを読み込み、その後require_treeでそれ以外のすべてのファイルを読み込む。

 

Rails – 掲示板 – 第1段階

概要

掲示板を例にして、ユーザーの登録、サインインを実装する。サインイン済みの場合のみトップページを表示するアクセス制限も実装する。

掲示板の全体ページへ

要件

画面遷移

  • アクセス時に/topにルーティング
    • サインイン状態でなければ/sign_inにルーティング
    • 仮表示として登録されているユーザー名、メールアドレス一覧を表示
    • ログアウト
      /sign_in
  • /sign_in
    • リンクをクリックして/sign_up
    • ユーザー名、パスワードを入力
      /top
  • /sign_up
    • リンクをクリックして/sign_in
    • ユーザー名、メールアドレス、パスワードを入力してユーザー登録
      /top

データベース

登録ユーザーテーブル:users

カラム名 型(MySQL) 型(Rails) 内容
id BIGINT(AI) Rails生成
name VARCHAR(255) string ユーザー名
email VARCHAR(255) string メールアドレス
pasword VARCHAR(255) string パスワード
created_at DATETIME Rails生成
updated_at DATETIME Rails生成

検討

コントローラーとアクション

pages_controller.rb

  • トップページなどサイト全体に関するページのコントローラー
  • top:サインインユーザーに対するサイトのトップページをレンダリング

users_controller.rb

  • ユーザーの登録、サインインなどユーザー管理を担うコントローラー
  • sign_in:サインインページをレンダリング
  • sign_up:サインアップページをレンダリング
  • sign_in_process:サインインフォームのPOSTに対するサインイン処理
  • sign_up_process:サインアップフォームのPOSTに対するサインアップ処理

ビューファイル

pages

  • top.html.erb:サインインユーザーが最初に見るページ
    • BBSの記事などが載ることになるが、この時点では登録済みのユーザーリストを表示する
    • ヘッダーメニューを表示する

users

  • sign_up.html.erb:未登録ユーザーのためのサインアップページ
  • sign_in.html.erb:登録ユーザーのためのサインインページ
  • これらのページにはヘッダーメニューは表示されない

共通のビューファイル

共通のビューファイルはlayoutディレクトリーに置く。サインインの有無に対応したレイアウトを分け、デフォルトでない場合はコントローラーから明示的に呼び出して使い分ける。

  • application.html.erb:サインイン済みのユーザーに対しては登録やサインアウトといった処理のメニューをヘッダーに表示する
  • application_signed_out.html.erb:サインインしていないユーザーに対してはヘッダーメニュを表示しない

スタイルファイル

CSSのスタイルをリセットするファイルを準備。

  • reset.css

ヘッダーメニューのスタイルファイルを独立して準備。

  • header.scss

各ビューのスタイルファイルはコントローラー単位のファイル。

  • pages.scss
  • users.scss

実装手順

 

 

Rails – 画像ファイルの配置とパス指定

概要

Railsで画像ファイルを配置するのは以下の2箇所

app/assets/images
開発側で準備するロゴやアイコンなど
public
ユーザーのアップロード画像など

それぞれの下にディレクトリーを作って、その中の画像ファイルをimg要素、div要素の背景画像で読み込む場合のパス指定について整理した。

ビューファイル&img要素の場合

app/assets/images

サブディレクトリ―exampleの下にimage_assets.jpgを置いた場合。

example/ファイル 読み込めない
/example/ファイル 読み込めない
./example/ファイル 読み込めない

public

サブディレクトリ―exampleの下にimage_public.jpgを置いた場合。

example/ファイル 読み込める
/example/ファイル 読み込める
./example/ファイル 読み込める

ビューファイル&img_tagの場合

app/assets/images

サブディレクトリ―exampleの下にimage_assets.jpgを置いた場合。

example/ファイル 読み込める
/example/ファイル 読み込めない
./example/ファイル NoMethodError

public

サブディレクトリ―exampleの下にimage_public.jpgを置いた場合。

example/ファイル Sprockets::Rails::Helper::AssetNotFound
/example/ファイル 読み込める
./example/ファイル NoMethodError

SCSS&div要素の背景画像の場合

app/assets/images

サブディレクトリ―exampleの下にimage_assets.jpgを置いた場合。

example/ファイル 読み込める
/example/ファイル 読み込めない
./example/ファイル 読み込めない

public

サブディレクトリ―exampleの下にimage_public.jpgを置いた場合。

example/ファイル 読み込めない
/example/ファイル 読み込める
./example/ファイル 読み込めない

まとめ

img要素はpublicの画像は読めるがassetsの画像は読めないので、img_tagヘルパーを使う方がよい。画像をimg_tagで配置する場合も、div要素の背景画像とする場合も、ファイルのパス指定は以下の通り。

パス指定
app/assets/images サブディレクトリ―/ファイル
public /サブディレクトリ―/ファイル

参考

確認に使ったアプリケーションファイル

pages_controller.rb

image_location.html.erb

pages.scss

 

Rails – スタイル設定

概要

Railsのプロジェクトにおけるスタイルシートの場所、スタイル設定について整理する。

デフォルトの状態

プロジェクト生成直後、app/assets/stylesheets/ディレクトリーにapplication.cssが生成され、以下の2行が記述されている。これらの行はディレクティブと呼ばれ、それぞれの意味については後述。

この段階でRailsの”Yay! You’re on Rails!”のページのソースを見ると、HTMLに直接styleタグが書かれている。

コントローラーとスタイルファイルの関係

以下のように2つのアクションを含むコントローラーを3つ生成する(出力は省略)。

その結果、コントローラー・ビューファイルとともに、app/assets/stylesheetsディレクトリーに3つのscssファイルが生成される。

これら3つのscssファイルはコメントのみの空の内容。

ここでorangeビューファイルを表示させてみる。

localhost:3000/fruits/orange

表示されたページのソースのうちスタイルシートの読み込みに関する行を抜き出すと以下のとおり。

以下のことがわかる

  • applicationのほか、新たに生成されたfruits, vesitables, meatsに関するスタイルシートが全て読み込まれる
  • スタイルシートはcss拡張子を持つ
  • ファイル名の本体は、コントローラー名.self-ダイジェストの形式
  • URLクエリーパラメーターを持つ(body=1)
  • スタイルが読み込まれる順番は、application.cssが最後で、その前に他のファイルが辞書順で読み込まれる

これらのファイルは元のscssファイルからcssにコンパイルされた結果で、ファイルの内容のダイジェストが元のファイル名に付加されている。

この場合、application.cssと3つのscss全てのスタイルが適用される。たとえばいずれかのcss/scssファイルに* { color: red; }と記述するとfruits/orangeページの文字の色が赤くなる。

require_selfとapplication.css

無指定でもapplication.cssは読み込まれる

application.cssの以下の2行を削除し、何も指定されていない状態にする。

この状態でorangeページを表示させてソースを見ると、application.cssの読み込みだけ残っている。

require_selfの意味?

application.cssの2行の記述のうち*= require_tree .の行を削除し、ページを表示させてソースを見てみる。

*= require_selfの行に対応してapplication.cssのファイルが読み込まれているが、そもそもなにも指定しなくてもこの行は生成されていた。

次に*= require_selfの方を削除し*= require_tree .を残した結果を見てみる。無指定の時と同じく、ここでもapplication.cssが読み込まれている。

読み込み順の制御は可能

require_treeとrequire_selfの順番を逆にしてみる

そうすると、application.cssが最初に読み込まれるようになった。

ディレクティブ

require_tree

stylesheetsディレクtリーの構成を以下の様に変更する。

  • d:stylesheets
    • f:meats.scss
    • d:crops
      • f:vesitables.scss
      • d:fruits
        • f:fruits.scss

この状態でapplication.cssが初期設定のとき、ページを表示させてもスタイルファイルの読み込みは変わらない。

require_tree .はカレントディレクトリー以下のすべてのディレクトリをたどりながらすべてのファイルをCSSに含める。

次にapplication.cssの内容を以下の様に変更する。

この結果、指定したcropsディレクトリー以下のファイルが再帰的に読み込まれる(application.cssは読み込まれている)。

require_directory

require_directoryは、指定したディレクトリー下のファイルのみをCSSに含める。サブディレクトリー以下は無視される、

この結果は、cropsディレクトリー下のvesitables.cssファイルのみが読み込まれる(application.cssは読み込まれている)。

require ファイル

requireディレクティブにファイル名を指定して、特定のファイルのみを読み込める。

上記の指定で、HTMLファイルにはfruits.cssのみが読み込まれる(application.cssは読み込まれている)。

 

Rails – 基礎的なルーティング

概要

GETやPOSTなどのリクエストがあったときconfig/routes.rbの内容に従って各コードにルーティングされる。

このルーティングファイルの書き方を整理する。

前提

以下のような構成のアプリケーションを考える。

  • コントローラー:pages_controller.rb
    • アクション:top
    • ビュー:top.html.erb
  • コントローラー:users
    • アクション:sign_up、sign_in
    • ビュー:sign_up.html.erb、sign_in.html.erb

デフォルトのroutes.rb

設定と動作

ルーティングファイルはconfig/routes.rbにある。コントローラー生成直後のファイルの内容は以下のとおり。

初期状態では、GETメソッドで各ビューファイルがリクエストされたとき、ディレクトリー構成に従ってファイルを探すようルーティングされる。

たとえばブラウザーでhttp://localhost:3000/pages/topと入力するとpagesディレクトリー下のtop.html.erbが表示される。

このページに他のページからヘルパーでリンクを張る場合は以下の様に書く。

<%= link_to 'トップ', '/pages/top %>

ルーティング

ルーティングの設定状態はrails routesコマンドで確認できる。

Prefixの列はリンクのエイリアスに関する表示で、ヘルパー中でプレフィックスに'_path'を付けた名前でリンク先を表せる。

たとえばtop.html.erb中に以下の行を追加するとリンクが表示され、クリックするとsign_in.html.erbページに遷移する。

<%= link_to('サインイン', users_sign_in_path) %>

まとめ

  • ルーティング設定で各アクションを呼ぶためのURLを設定できる
  • URLでルーティングする場合は文字列とする
  • Prefix_pathを組み合わせたエイリアスでもルーティングができ、その場合はコロンなしで書く

ルーティングの設定変更

設定と動作

コントローラー生成時のルーティングを変更して、それぞれのページがアプリケーションルートから直接呼び出せるようにする(たとえばlocalhost:3000/topなど)。

3つのルーティングとも同じ方法で指定している。

メソッド 'URL', to: 'コントローラー#アクション'

これでそれぞれのURL指定’/top’などに簡略化され、GETリクエストに対して対応するアクションが実行される。

この場合、トップページに以下のようなURL指定のリンクを追加すると、クリック時にサインインページに遷移する。

<%= link_to('サインイン', '/sign_in') %>

ルーティング

ルーティングの一覧は以下のとおりで、Prefixの列も簡略化されている。

Prefixも変更されているので、top.html.erb中に以下の行を追加するとリンクが表示され、クリックするとsign_in.html.erbページに遷移する。

<%= link_to('サインイン', sign_in_path) %>¥

まとめ

  • ルーティングの, to: 'controller#action'によって、設定したURLから指定したアクションにルーティングできる
  • カンマ、toキー(to:)、'コントローラー#アクション'の文字列

ルーティングの名前

設定と動作

routes.rbのsign_inの行に, as:を追加して以下の様に変更する。

get '/sign_in', to: 'users#sign_in', as: :sign_in_page

この場合、リンク先としてsign_in_page_pathを指定してルーティングできるようになる。

ルーティング

このときのルーティングは以下の様になっている。

この場合、linkt_toから呼び出す名前はsign_in_page_pathになり、従前のsign_in_pathを使うとエラーになる。

つまり、as:で指定された内容で元のPrefixがオーバーライドされ、以後はその内容の名前かURLで指定しなければならない。

まとめ

  • ルーティングの名前を', as: :name'で設定できる
  • 設定はカンマ、asキー(as:)、名前シンボル
  • 名前を設定すると、Prefixがそれに置き換えられる