Rails – 掲示板 – ユーザー認証機能

概要

サインアップしたユーザーが、メールアドレスとパスワードでサインインし、サインアウトする機能を実装する。

セッションによるアクセス制限などの管理は後に実装し、ここではユーザー認証とページ遷移だけにとどめる。

掲示板の第1段階へ

サインイン機能

サインイン処理アクション

サインインが要求されたとき、sign_inアクションからサインインのビューがレンダリングされる。ビューのフォームとの間でUserモデルを介してデータをやりとりするので、アクションでUserモデルのインスタンスを生成しておく。

フォームでのモデルの設定

サインインのビュー、sign_in.html.erbform_withヘルパーで、コントローラーで生成されたUserモデルのインスタンスを指定する。

app/views/users/sign_in.html.erb

サインイン処理

サインインフォームの入力情報は、users_controllersign_in_processアクションにPOSTされる(ルーティングは「フォームの入力を確認する」で設定した)。

users_controllerに、以下のsign_in_processメソッドを追加する。

処理の流れは以下のとおり。

  1. POSTされたデータをuser_paramsメソッドにより受け取る(user_paramsについてはform_withとモデルの使い方を参照)
  2. user_paramsを使って入力データがセットされたUserインスタンスを生成
  3. ユーザー登録時と同じ方法で暗号化されたパスワード(ダイジェスト)を生成
  4. メールアドレスとパスワードダイジェストで、データベースからユーザーを検索
  5. ユーザーが存在する場合、サインインとしてtopページにリダイレクト
  6. ユーザーが存在しない場合、エラーメッセージをセットして再度サインイン画面をレンダリング(@userに入力データがセットされているので、サインイン画面にメールアドレスが残る)

サインアウト機能

サインインに成功すると、トップ画面に遷移する。

トップ画面を始めサインイン後にアクセス可能な画面は全てヘッダーメニューを持つ。そのメニュー中、サインアウトの項目をサインイン画面へのリンクとする。

 

Rails – 掲示板 – サインアップ機能

概要

サインアップ機能では、フォームで入力されたユーザー情報をデータベースに登録する。

データベースの構築、テーブルのマイグレーション、モデルによるDBの操作を整理する。

掲示板の第1段階へ

データベースの準備

データベースの準備」の要領でプロジェクトで扱うデータベースを準備する。

database.yml

development用のデータベースのみ準備し、testとproductionではデータベースを作成しない設定とする。

config/database.yml

DB作成

rails db:createでデータベースを作成し、rails db:consoleでmysqlコンソールに入り、データベースが作成されていることを確認。

モデルの生成とマイグレーション

モデルを生成し、これに対応したテーブルをマイグレーションにより生成する(基本的な方法はこちら)。

第1段階の最初で設定したデータベースのカラムを指定してモデルを生成する。idcreated_atupdated_atの3つはRailsが自動的に付加するので、以下の3つのみ指定する。

  • name:string
  • email:string
  • password:string

モデル名、モデルファイル名などの対応は以下の通り。

モデル名 user
モデルクラス名 User
モデルファイル名 user.rb
テーブル名 users

モデルの生成には、rails generate modelコマンドを使う。

rails generate model model_name col1:type col2:type ...

app/modelsディレクトリーにモデルファイルuser.rbが生成される。

app/models/user.rb

同時に、dbディレクトリーにマイグレーションファイルが生成される。

ファイル名は20210320060906_create_users.rbで、日時がUSTとなっている。

db/20210320060906_create_users.rb

rails db:maigrateコマンドを実行すると、マイグレーションファイルの内容に従ってテーブルが作成される。

rails dbconsoleコマンドを実行すると既にプロジェクトのデータベースを使う状態になっていて、usersテーブルが作成されているのが確認できる。

フォームデータのデータベースへの登録

フォームデータの取得

モデルによるフォーム入力への変更

フォーム入力の確認ではURL(アクション)を指定してデータを送信した。

モデルを使う場合には、モデルのインスタンスを生成して、そのインスタンスを介してデータを扱う。そのために以下の2点を変更する。

まずフォームでモデルを指定するため、その実行前、sign_upで空のUserクラスのインスタンスを準備する。結果はコントローラーのインスタンス変数@userに格納し、フォームがあるビューでも利用可能なようにしておく。

app/controllers/users_controller.rb

次に、フォーム側でモデルに入力データを格納するように変更する。form_withの場合は:modelキーで@userを指定する(form_forを使う場合は単に第1引数に@userを指定する)。

app/views/users/sign_up.html.erb

モデルのパラメーターの一括取得

モデルによるフォームデータの取得を参考に、require.permitによるメソッドを準備しておく。

app/controllers/users_controller.rb

データ保存の枠組み

フォームの入力データを単に保存する、というだけの手続きであれば、以下の処理になる。

  1. フォームからデータがPOSTされる
  2. それがsign_up_processにルーティングされる
  3. sign_up_processアクション内で
    1. フォームに入力されたパラメーターで新たなUserモデルのインスタンスを生成
    2. そのインスタンスの内容でデータベースに書き込み

フォームへの入力後、サインアップのボタンを押した後のテーブルの内容を確認すると、データは登録されている。

入力データの検証と書き込み

入力データのバリデーション

入力データのバリデーション処理を記述する。検証内容は以下の通り。

:name :email :password
存在 空ではない 空ではない 空ではない
一意性 一意 一意 一意
長さ 20文字以下 80文字以下 6文字以上
書式制約 なし あり なし

モデルのデータのバリデーションは、モデルクラス内で以下を宣言する。実行はsavecreateupdateの時に実行される。

validates: 対象カラム, 検証条件, 検証条件, ...

userモデルへのバリデーションの実装は以下の通り。

メールアドレスについては正規表現によりパターンチェックしている。

  • ローカル部は単語形成文字(a-z, _)2文字以上で間に連続しないドットをはさんでよい
  • ドメインは単語形成文字で間に連続しないドットをはさんでよく、最後にTLD(top level domain)が必要

エラー表示

モデルにvalidatesを定義すると、user.saveでデータベースに登録する前にバリデーションが実行される。

検証結果が適正であればデータは登録され、user.saveの戻り値はtrue。不適正であればデータは登録されず、user.saveの戻り値はfalseになる。

適正に登録された場合はトップページに遷移し、登録成功した旨のメッセージを一定時間表示する。一方不適正な場合は再度サインアップページを表示し、入力が不適正な旨のメッセージを一定時間表示する。

ページ遷移の際に一定時間メッセージを表示して消す機能についてはflushの使い方を参照。

コントローラーでの処理

  1. フォームからPOSTされたデータをで受け取り、user_paramsメソッドを介してモデルを生成
  2. テストのため、valid?メソッドでバリデーション実行
  3. 検証の結果が適正か不適正かによってflash.nowに保存
  4. 共通レイアウトを指定し、適正ならsign_inを、不適正ならsign_upをレンダリング

app/controllers/users_controller.rb

flash.nowを使っている理由は以下の通り。

  • エラー後の再入力で、直前に入力した値をフォームに入れておきたい
  • そのためにはインスタンス変数@userを使う必要がある
  • ただしredirect_toでアクションから実行すると@usernilに初期化されてしまう
  • そこでrender@userの内容を保持したい
  • そうすると、flashではその次のアクションまで内容が保持されて余計な表示がされることがある
  • そこで適正・不適正ともflash.nowrenderを使った

また、17行目の処理は以下の通り。

  • @user.errors.messagesはメッセージタイプをキーとするハッシュ
  • ハッシュの値は検証結果のメッセージの配列
  • まずvaluesmessagesの全てのメッセージタイプの値を取り出す(メッセージ配列を要素とする配列)
  • flattenで1次元のメッセージの配列にする
  • joinで配列要素を文字列に結合(区切りは<br>タグ)

レイアウトでの表示

  1. JQueryを使うのでCDNから読み込み(9行目)
  2. flash.nowが設定されていればメッセージを表示
    • 表示するp要素のクラスをタイプごとに設定
    • メッセージ中の<br>タグを有効にするため、html_safeを適用
  3. 3秒後にメッセージをスライドアップするJavaScriptを記述

app/views/layouts/application_signed_out.html.erb

スタイルの設定

  • .flash_messageで共通のスタイルを定義
  • success/dangerに応じて設定されたクラスごとに色を変える

app/assets/stylesheets/common.scss

DB書き込み処理

@user.valid?でメッセージの内容や挙動を確認したら、ここを@user.saveに書き換える。

データを1つ登録した結果。

以降、重複する内容のデータで登録しようとするとuniquenessで弾かれる。

パスワードの暗号化

パスワードの暗号化はDigest::MD5を使うuserモデルに以下を追記する。

before_saveでコールバックを設定していて、モデルの内容がデータベースに書き込まれるときにパスワードが暗号化される

当初これをbefore_saveとしていたが、これだと後述のデータ更新のときにもコールバックが実行され、既にハッシュ化されているパスワードが更にハッシュ化されて登録されていまう。このため、これをbefore_createに変更。

before_createでコールバックを設定していて、モデルの内容でデータベースのレコードが新規作成されるときにパスワードが暗号化される。

以下はテストデータを登録した結果。

 

Rails – コールバック

概要

コールバックは、validationsaveなどの処理の前後に登録した関数を実行させるよう設定する。

コールバックの種類

オブジェクトの生成

  • before_validation
  • after_validation
  • before_save
  • around_save
  • before_create
  • around_create
  • after_create
  • after_save
  • after_commit/after_rollback

オブジェクトの更新

  • before_validation
  • after_validation
  • before_save
  • around_save
  • before_update
  • around_update
  • after_update
  • after_save
  • after_commit/after_rollback

オブジェクトの消去

  • before_destroy
  • around_destroy
  • after_destroy
  • after_commit/after_rollback

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

実装手順