どうも!chuckです。
早いもので、このシリーズも10回目ですね〜。今回はユーザーモデルに対して色々な制約をかけていきますヽ(=´▽`=)ノ
今回はRubyOnRailsチュートリアル6章の内容にほぼ準拠しています。
RSpecを使ったUserモデルのテスト
前回までで、Userモデルに対するテストは以下のようになっています。
5行目のbeforeブロックを使って前処理をしています。処理の内容は、新しくUserのインスタンスを作成して、userインスタンス変数に格納しています。
7行目では、subjectブロックを使ってテストサンプルのデフォルトとして@userを設定しています。
9,10行目では、オブジェクトが各々の属性に反応するかを確認しています(よくわからない…)
ここまでが基本的なテスト。
bundle exec rspec spec/ を実行するとテストにパスしますヽ(=´▽`=)ノ
ここからはUserモデルに対する4つの検証を行っていきます。
1,存在性(presense)の確認
Userモデルを作成して保存する際に、name属性とemail属性が存在することを確認します。NotNull的なことかな??
検証をするためには、app/model/user.rbファイルにvalidateメソッドを加えます。
validates :name, presenece: true と書くことでname属性が必須となります。この状態でname属性が空のデータを保存しようとするとエラーになります(作成自体はできる)
Rails consoleでの確認。
userのname属性が空だった時のテストを書きます。
spec/model/user_spec.rb
テストの結果は成功になります。
ただし、validateメソッドをコメントアウトするとエラーになってしまうことから、存在性の確認が正常に働いていることがわかります。
これで、ユーザー登録の際に名前が必須となりました。(Emailにも同様の処理を行います)
2,長さ(length)の検証
データの長さに対する制限を加えます。
spec/model/user_spec.rb
長さに対する検証は lengthとを使います。
app/model/user.rb
3, フォーマットの検証
メールアドレスの検証も実施しますが、ちょっと工夫をします。こちらがRSpecへの追記。
spec/model/user_spec.rb
上のブロックでは無効なアドレスが不正になることを、下のブロックではその逆を検証しています。
31,42行目の %wは文字列の配列を作成し、それに対してeachで各々に処理を行っています。
フォーマットの検証には format を使います。
3行目で正規表現の定数を作成し、4行目でformatに渡しています。
4, 一意性の検証
そのデータが唯一無二であり、他のデータと被っていないことを検証します。ただし、今回のテストは今までと異なり、実際にデータを登録する必要があります。
追記するテストがこちら。
spec/model/user_spec.rb
@user.dupはデータを複製しています。これを.saveすることで、作成したデータと同様のデータを事前に登録することができます。
このうえでデータを登録すると、既に存在するのでエラーになることを確認します。
app/model/user.rb
9行目に一意性を強いることを追記しました。
ただし、更に変更を加えてメールアドレスの大文字と小文字を無視するようにします。
case_sensitive: falseとすることで大文字と小文字を無視するようになります。
ただし、ここでは念の為にメールアドレスに対してさらにユニーク性を高めます。
rails generate migration add_index_to_user_email を実行します。うわーこれカラムに追加でやったやつだ!
出来上がったファイルにこのように記述。
add_iindexメソッドを利用して、emailカラムをユニークにしています。
マイグレーションファイルを作成したので、bundle exec rake db:migrate を実行。
すると、db/schema.rbが以下のように変更されます。
23行目に追記されたことがわかります。
ただし、もう1つやることがあります。それはデータを保存する前にメールアドレスを全部小文字に変換する作業です。
データベースのアダプタが常に大文字と小文字を区別するindexを使ってるかどうか分からないから、らしい。(ふーん)
そのためにコールバックというメソッドを使います。ActiveRecordに何かをしてもらう便利なメソッドのよう。
app/model/user.rb
2行目のbefore_saveがコールバックです。保存する前にブロック内の処理を行ってくれます。ブロック内では、.downcaseメソッドを使ってメールアドレスを小文字に変換しています。
長くなりましたが以上で検証は終わりですヽ(=´▽`=)ノ
今回施した検証。
- 存在性(presence)
- 長さ(length)
- フォーマット(format)
- 一意性(unique)
まとめ的な
ユーザモデルに対して制約をかけました。単語データの方は制約も何もあったもんじゃないので笑、いかにもモデルの作成って感じで楽しかったです!
さらに、制約をかけつつRSpecも書けて良かった!Railsチュートリアルで2回やってるはずなのに、今回ようやく制約とそのテストを理解できたように思います(´ω`)
次回はユーザーモデルに安全なパスワードを付け加える予定です(`・ω・´)ゞ
Railsチュートリアル
Follow Me
railsのsubjectって入れ子にして上書きできるのね!
— タク(chuck) (@chuck0523) 2015, 7月 21