らくだ🐫にもできるRailsチュートリアル|6.2

6.2 ユーザーを検証する

Validation(検証)機能を実装する

6.2.1 有効性を検証する

Userモデルにバリデーションを設定していないため
無効になる内容が無い→GREEN

演習

  1. コンソールから、新しく生成したuserオブジェクトが有効 (valid) であることを確認してみましょう。
  2. 6.1.3で生成したuserオブジェクトも有効であるかどうか、確認してみましょう。

バリデーションが無いので略

6.2.2 存在性を検証する

Presenceとはなんぞ

存在を検証するメソッド

user.nameに対するバリデーションを設定する

バリデーションヘルパーとは何ぞ

バリデーション用のヘルパー(ざっくり)
いろんな種類が用意されている
バリデーションヘルパー←RailsGuideの該当箇所

user.nameが空白だとfalseが返るのバリデーションを設定したので
name should be presentのテストが成功する

errors.full_messagesとはなんぞ

起こっているエラーを用意されているメッセージで教えてくれる便利なチェーンメソッド。
多分詳しくは後から出てくると思うのです。

email属性の存在性を検証する

演習

  1. 新しいユーザーuを作成し、作成した時点では有効ではない (invalid) ことを確認してください。なぜ有効ではないのでしょうか? エラーメッセージを確認してみましょう。
  2. u.errors.messagesを実行すると、ハッシュ形式でエラーが取得できることを確認してください。emailに関するエラー情報だけを取得したい場合、どうやって取得すれば良いでしょうか?

6.2.3 長さを検証する

名前には50文字まで
メールアドレスには255字までの上限を設ける

まずはテストから。

演習

  1. 長すぎるnameとemail属性を持ったuserオブジェクトを生成し、有効でないことを確認してみましょう。
  2. 長さに関するバリデーションが失敗した時、どんなエラーメッセージが生成されるでしょうか? 確認してみてください。

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

有効なメールアドレスかどうかの判定

上記のテクニックを利用してメールアドレスのフォーマットの検証のテストを書く
→有効なメールアドレスと無効なメールアドレスをいくつか用意してエラーを検知していく

formatヘルパー

validates :email, format: { with: /正規表現/ }
withオプションで与えられた正規表現と属性の値がマッチするか検証するためのヘルパー

正規表現とは

Regular Expression、regexとも表記される


そういう記法があると言う事(ざっくり)

有効なメールアドレスだけにマッチして、無効なメールアドレスにはマッチしない正規表現を組み立てる必要があります。

上記のような正規表現を組み立ててemailの値をマッチするかを検証する
→VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
この正規表現に関する本文の解説を見る
Rubular(正規表現を試せるWebサイト)

現状の正規表現には問題が残っている→演習で修正

定数ってなんだっけ

変数→代入した値を後から変更することが出来る
定数→代入した値を後から変更することが出来ない
文字通りですね
定数→Rubyでは再代入しようとすると注意文が出るが代入できてしまう
でもしないでね!分かってるよね!!と言う事らしいっぽい
Rubyでは定数は大文字で始める → 暗黙のルール的な物で全部大文字が良い
→メールアドレスのフォーマットの正規表現は変更させたくないので定数に代入する

  1. リスト 6.18にある有効なメールアドレスのリストと、リスト 6.19にある無効なメールアドレスのリストをRubularのYour test string:に転記してみてください。その後、リスト 6.21の正規表現をYour regular expression:に転記して、有効なメールアドレスのみがすべてマッチし、無効なメールアドレスはすべてマッチしないことを確認してみましょう。
  2. 先ほど触れたように、リスト 6.21のメールアドレスチェックする正規表現は、foo@bar..comのようにドットが連続した無効なメールアドレスを許容してしまいます。まずは、このメールアドレスをリスト 6.19の無効なメールアドレスリストに追加し、これによってテストが失敗することを確認してください。次に、リスト 6.23で示した、少し複雑な正規表現を使ってこのテストがパスすることを確認してください。
  3. foo@bar..comをRubularのメールアドレスのリストに追加し、リスト 6.23の正規表現をRubularで使ってみてください。有効なメールアドレスのみがすべてマッチし、無効なメールアドレスはすべてマッチしないことを確認してみましょう。

1.eachメソッドでそれぞれのアドレスを取り出してから張り付けると○

2.3.動作確認のみにて省略

使われている正規表現の内容

/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
/ 正規表現の開始
\A 文字列の先頭
[\w+\-.]+ 英数字、_、+、-、.のいずれかを少なくとも1文字以上繰り返す
@ アットマーク
[a-z\d\-]+ 英小文字、数字、-のいずれかを少なくとも1文字以上繰り返す
(\. [a-z\d\-]+)* (ドット 英小文字、数字、-のいずれかを少なくとも1文字以上繰り返す)←これを0回以上繰り返す
\. ドット
[a-z]+ 英小文字を少なくとも1文字以上繰り返す
\z 文字列の末尾
/ 正規表現の終了
i 大文字小文字を無視

6.2.5 一意性を検証する

一意性とは何ぞ

他に同じデータはない、と言うこと(ざっくり
→沢山ある値の中から1つの情報を特定できる
バリデーションには:uniqueを使って設定する

一意性のテスト

一意性のテストのテストの為には実際にデータベースに情報を登録する必要がある
→テスト専用のデータベースdb/test.sqlite3がある

まずはテスト

@user.dupとは

dupは同じ属性を持つデータを複製するメソッド
上記の場合@userを保存済なので、
複製されたユーザーのメールアドレスは既に存在しており無効になる

メールアドレスでは大文字小文字が区別されない

現在のテストではfoo@bar.comとFOO@BAR.COMは別の物に判断されるが
実際は大文字と小文字で区別はされないため
検証でもメールアドレスの大文字と小文字が区別されないように書く必要がある

case_sensitive

uniqueness:ヘルパーのオプション
一意性制約で大文字小文字を区別するかどうかを指定するもの
uniqueness:値が一意であるかの検証にcase_sensitive: false(大文字と小文字を区別しない)というオプションを追加している

インデックスを追加する

それはActive Recordはデータベースのレベルでは一意性を保証していないという問題です。具体的なシナリオを使ってその問題を説明します。
(中略)
上のシナリオが信じがたいもののように思えるかもしれませんが、どうか信じてください。RailsのWebサイトでは、トラフィックが多いときにこのような問題が発生する可能性があるのです

→解決するためにemailのカラムにindexを追加する
データベースのインデックスに関するコラム

テストDB用のサンプルデータが含まれているfixtures内で一意性の制限が保たれていないため、テストは red になります。

fixtureとはなんぞ

→テストDB用のサンプルデータが含まれるファイル

6.1でUserモデルを作成した際、
自動で生成されていたUserのデフォルトfixture内のデータで一意性の制限が保たれていない
→今はまだ使わないのでひとまずデータを削除しておく

データベースに保存される直前にすべての文字列を小文字に変換する

データベースによっては大文字と小文字を区別するものがあるため
Railsチュートリアルでは「データベースに保存される直前にすべての文字列を小文字に変換する」
(多分色々な方法があるんだと思う)
コールバックメソッドのbefore_saveを使って、オブジェクトが保存される時点で処理を実行する

コールバック (callback) メソッドとはなんぞ

オブジェクトの状態が切り替わる際の特定の瞬間に呼び出されるメソッド
→before_save saveの直前
railsガイドのコールバックのページ

これで、先に述べたアリスのシナリオはうまくいくようになります

良くわからないんですが、正気を失わずに済むと言う事です?
→ちょっと上のせっかちなアリスちゃんがSubmitを2回押しちゃったっていう話でCoCとは関係なかったっぽい

演習

  1. リスト 6.33を参考に、メールアドレスを小文字にするテストをリスト 6.32に追加してみましょう。ちなみに追加するテストコードでは、データベースの値に合わせて更新するreloadメソッドと、値が一致しているかどうか確認するassert_equalメソッドを使っています。リスト 6.33のテストがうまく動いているか確認するためにも、before_saveの行をコメントアウトして redになることを、また、コメントアウトを解除すると greenになることを確認してみましょう。
  2. テストスイートの実行結果を確認しながら、before_saveコールバックをemail.downcase!に書き換えてみましょう。ヒント: メソッドの末尾に!を付け足すことにより、email属性を直接変更できるようになります (リスト 6.34)。

1.本文通り
2.
before_save { self.email = email.downcase } → before_save { email.downcase! }
emailを直接変更しているので代入する必要が無い(コードが短く済む!)

まとめとか感想

良くわからない部分が多くて
時間も長かったし量も長かった!
けど、しっかり身になったのではないでしょうか?!
身に?実に?

らくだ🐫にもできるRailsチュートリアルとは

「ド」が付く素人のらくだ🐫が勉強するRailsチュートリアルの学習記録です。
自分用に記録していますが、お役に立つことがあれば幸いです。

調べたとはいえらくだ🐫なりの解釈や説明が含まれます。間違っている部分もあるかと思います。そんな所は教えて頂けますと幸いなのですが、このブログにはコメント機能がありません💧お手数おかけしますがTwitterなどでご連絡いただければ幸いです