Rails

挫折しないRailsチュートリアルまとめ【第6章】

Railsチュートリアル6章を走破しました。

Railsチュートリアル6章の内容

  • ユーザーのデータモデルの作成
  • データを保存する手段の確保

6.1 Userモデル

6.1.1 データベースの移行

  • Railsはデータを保存する時にデフォルトでRDB(リレーショナルデータベース)を使用する
  • モデルを作成する構文は以下のとおり
  • コントローラを作成する場合には「複数形」、モデルを作成する場合は「単数形」を指定する
  • 上記コマンドを実行した結果、マイグレーションファイルというデータベース更新情報が記述されたファイル(db/migrate/日付_create_テーブル名.rb)と、モデルのコードファイル(app/models/モデル名.rb)が作成される
  • マイグレーションファイルはデータベースへの変更を定義した「changeメソッド」の集まり
  • モデル名は「単数形」だがテーブル名は「複数形」となる
    (モデルはひとつのを表すが、テーブルはモデルの集合体であるため)
  • モデルを作成する時に「id」という各レコード(行)を一意にするカラム(列)が自動的に作成される
  • モデルを作成する時に「created_at」「udpated_at」というカラム(列)が自動的に作成される(「changeメソッド」の「t.timestamp」の記述によって)
  • マイグレーションファイルの内容をデータベースに反映時には以下のコマンドを実行する
  • マイグレーションした内容を元に戻したい場合は以下のコマンドを実行する

6.1.2 modelファイル

  • 特になし

6.1.3 ユーザーオブジェクトを作成する

  • Railsコンソールでの更新結果をデータベースに反映したくない場合はRailsコンソールをサンドボックスモードで起動すると、Railsコンソール終了時に全てロールバックされる
  • モデルから作成したオブジェクトが有効であるか確認するには「valid?メソッド」を使う
  • オブジェクトの内容をデータベースに保存する時は「saveメソッド」を使う。
    保存が成功した場合はtrue、失敗した場合はfalseが返る。
  • 「saveメソッド」実行時に「id」「crated_at」「updated_at」の値が生成され、オブジェクトともデータベースにも反映される
  • 「crateメソッド」を使用すると「newメソッド」と「saveメソッド:を同時に行い、対象のオブジェクト自体を返す
  • 「destroyメソッド」は「crateメソッド」と逆の機能で、対象のオブジェクトを返す(メモリ上に残っている)

6.1.4 ユーザーオブジェクトを検索する

  • 「モデル名.find(id)」で指定したidのデータを検索し、見つかった該当のオブジェクトを返し、見つからなかったら例外(ActiveRecord::RecordNotFound)が発生する
  • 特定のカラムの値でデータを検索する場合は、「モデル名.find_by(カラム名: カラム値)」で検索できる
  • 「モデル名.first」でデータベースの先頭を返す
  • 「モデル名.all・で全てのデータを返す

6.1.5 ユーザーオブジェクトを更新する

  • 生成したオブジェクトの「オブジェクト.カラム名 」に値を代入後に、「saveメソッド」を実行することでデータの更新が行える
  • 「saveメソッド」を実行する前に「reloadメソッド」を実行するとデータベースの情報を元にオブジェクトが再読み込みされ、更新前の値に戻る
  • 「update_attributesメソッド」を使用することで、データの更新と保存まで一度に行うことができる。
  • 「update_attributesメソッド」ではどれか1つのカラムでも検証に失敗すると、全てのカラムのデータ更新が失敗となる
  • 特定のカラムのみを更新したい場合は「「update_attributeメソッド」を使う。このメソッドはデータの検証は行われない

6.2 ユーザーを検証する

6.2.1 有効性を検証する

  • モデルのバリデーション(検証)機能はテスト駆動開発と相性が良い(まず失敗するテストを書き、次にテストを成功させるように実装する)
  • テストは有効なモデルのオブジェクトを作成し、その属性のうちの1つを有効でない属性を意図的に変更するように行う
  • 作成時の状態に対しても書いておくと、オブジェクトとバリデーションのどちらに問題があったかを切り分けしやすい
  • テストコードの例は以下のとおり(Userモデル)
  • モデルのテストのみを実行する場合は以下のコマンドを実行する

6.2.2 存在性を検証する

  • まず以下のようなテストを準備する
  • モデルの検証は「validatesメソッド」を使用する
  • 各カラムの存在を確認する場合は「validates :カラム名, presence: true」と記述する
  • 検証でエラーが発生した場合は「オブジェクト.errors.full_messages」で何でエラーとなったかのヒントが得られる

6.2.3 長さを検証する

  • まずは以下のようなテストを準備する
  • 各カラムの最大長さを検証する場合は「validates :カラム名, length: { maximum: 制限文字数 }」とする

6.2.4 フォーマットを検証する

  • まずは以下のようなテストを準備する
  • メールアドレスの検証は「formatオプション」を使う

6.2.5 一意性を検証する

  • メールアドレスは大文字、小文字を区別しないため、実際に一意性を検証しようとすると、大文字、小文字を区別しないような実装が必要
  • まずは以下のようなテストを準備する
  • 一意性を検証するには「:uniquenessオプション」を使う
  • 大文字、小文字を意識しないようにするには、さらに「:case_sensitiveオプション」を追加する(case_sensitiveがfalseのときuniquenessはtrueと判断される)
  • 上記のチェックを行ったとしても同時に複数のリクエストがあった場合に、バリデーションでは防げない場合があるので、データベースにインデックスを追加する必要がある
  • 後からデータベースの変更を行う場合は、まず以下のコマンドでマイグレーションファイルを作成する
  • 作成されたマイグレーションファイルに以下を定義して「rails db:migrate」する
  • データベースによっては大文字、小文字を区別しないものが存在するので、それに対応する必要もあり、モデルのバリデーションに以下を追加する必要がある

6.3 セキュアなパスワードを追加する

6.3.1 ハッシュ化されたパスワード

  • セキュアなパスワードの実装は「has_secure_passwordメソッド」を呼び出すことでほとんど完了する
  • 「has_secure_passwordメソッド」はUserを管理するモデルで以下のように記述するとで

     
has_secure_passwordメソッドを実装することで使える機能
  • ハッシュ化したパスワードをデータベースの「password_digest」という属性に保存できるようになる
  • 2つのペアの仮想的な属性(「password」と「password_confirmation)が使えるようになる
  • 存在値と値が一致するかどうかのバリデーションが追加される
  • 「authenticateメソッド」が使えるようになる
    (引数の文字列がパスワードと一致すると、Userを管理するオブジェクトを、一致しないとfalseを返す)
has_secure_passwordメソッドを使用するための条件
  • 「has_secure_passwordメソッド」を使用するにはデータベース「password_digest」というカラムが必要
  • ハッシュ関数「bcrypt」を使用するために「bcrypt」のgemのインストールが必要

6.3.2 ユーザーがセキュアなパスワードを持っている

  • 特になし

6.3.3 パスワードの最小文字数

  • 「変数 = 変数 = 値」ということで2つの変数に同時に同じ値を代入できる(多重代入)

6.3.4 ユーザーの作成と認証

  • 特になし

感想

内容としてはProgateで学習したユーザー認証+αの内容でしたが、メールアドレスの有効性を確認する大変さというか面倒くささが身にしみました。

でも、Webアプリにとってユーザー管理、認証をおろそかにすると、個人情報の流出などといった大変な事態に発展するのできちんとおさえて置く必要がありますね。

次の章では実際のユーザー登録フォームの作成に入るので、しっかりと身につけていきます。

ABOUT ME
Jyu2
ソフトウェア会社(SIer)で10年以上勤務のシステムエンジニア|ポケットWiFi使用歴2年以上|ポケットWiFi+αで快適でお得なインターネット環境を構築するための情報を発信|その他、IT情報やWebサービス、アプリ、ガジェットなどの情報を発信|自分と他の人のカバンの中身を紹介するメディア「カバンの中身ラボ(https://kaban-no-nakami-labo.com/)」も運営しています。 ポケットWiFi選びに迷ったらTwitter、お問合せフォームからご連絡ください。