Rails 6.0でアプリを開発 基本の流れ③
rails tutorialをベースとしてやってきていますが、6.0で違いがあった場合極力調べて基本の流れを押さえていこうと思いますが、もしかするともっといい使い方などあって修正することもあるかもしれません。今回はユーザー登録ページを作る際のメモ。
1.基本のデータモデル
ひとまずベースなので下記の要素で作成
id = itneger
name = string
email = string
2.Userモデルを生成
$ rails g model User name:string email:string
$ rails db:migrate
3.ユーザーの検証(validation)
バリデーションとして設定するのは
name: presence、length
email: presence、length、format、uniqueness
4.テスト駆動開発で作成
①テスト用にsetupメソッドで有効なオブジェクトを作成
②valid?で有効性を確認
③ここでテストを実行しようとするとエラーが発生
Migrations are pending. To resolve this issue, run:
rails db:migrate RAILS_ENV=test
→この通り
rails db:migrate RAILS_ENV=testを実行すると解除
5.存在性の検証(presence)
nameを空白にし存在性をテストする
テストはエラーになるので、Userモデルにバリデーションを設定
※バリデーションのコードは後でまとめて掲載
emailを空白にし存在性をテストする
テストはエラーになるので、Uesrモデルにバリデーションを設定
6.長さの検証(length)
nameを51文字、emailは244文字プラス@example.comで256文字でテストを設定
こちらもUserモデルにバリデーションを設定
7.emailのフォーマットの検証(format)
有効なメアドと無効なメアドを入れてテストを行う
こちらもUserモデルにバリデーションを設定
8.emailの一意性の検証(uniqueness)
一意性の検証では実際にデータベースにレコードがないと確認できないので注意
dupメソッドで複製を作り、saveして検証する
9.validationをUserモデルに設定
補足1)メアドのフォーマットと文字列の大文字小文字
メールアドレスのフォーマットはVALID_EMAIL_REGEXで設定しておく
通常メアドは大文字、小文字が区別されない
case_sensitiveオプションにfalseを指定することで、大文字小文字の差を無視する
補足2)トラフィックが多い時に発生しやすい一意性の弱点の補強
データベース上のemailのカラムにインデックス (index) を追加し、そのインデックスが一意であるようにする
①emailにindexを追加
$ rails g migration add_index_to_users_email
(既に存在するモデルに構造を追加するときはmigrationジェネレータを使用)
②データベース内でメアドの一意性を定義
③migrationの実行
$ rails db:migrate
10.テストを実行
※テストを行う前にusers.yml内に自動でできたデータはひとまず削除すること
ここでエラーが発生
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:
SQLite3::ConstraintException: UNIQUE constraint failed: users.email
C:/Users/81909/env/kaimono_app/db/migrate/20200211043622_add_index_to_users_email.rb:3:in `change'
bin/rails:4:in `<main>'
Caused by:
C:/Users/81909/env/kaimono_app/db/migrate/20200211043622_add_index_to_users_email.rb:3:in `change'
bin/rails:4:in `require'
bin/rails:4:in `<main>'
Caused by:
SQLite3::ConstraintException: UNIQUE constraint failed: users.email
C:/Users/81909/env/kaimono_app/db/migrate/20200211043622_add_index_to_users_email.rb:3:in `change'
bin/rails:4:in `require'
bin/rails:4:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
困ったときのRails console
①コンソールでUser.allで重複するユーザーがいないかチェックしたが当然レコードなし
②とりあえずUser.delete_allでデータベース内を一応0にした
ただし、まだエラーは解除されず
③rails db:migrate:resetをしようとしたところ再度エラー。
Permission denied @ apply2files - C:/Users/81909/env/kaimono_app/db/development.sqlite3 Couldn't drop database 'db/development.sqlite3' Errno::EACCES: Permission denied @ apply2files - C:/Users/81909/env/kaimono_app/db/development.sqlite3 bin/rails:4:in `require' bin/rails:4:in `<main>' Tasks: TOP => db:drop:_unsafe (See full trace by running task with --trace)
④Taskが db:drop:_unsafeに切り替わったので、これをやってみるとドロップできた
⑤その後rails db:migrate →成功
⑥rails test →rails db:migrate RAILS_ENV=testをしろというので行う → 成功
⑦rails test → 成功
11.DBに保存される前にemailのすべての文字列を小文字にする
注)すでに上記ruser.rb内には記述されているbefore_saveコールバック
大文字、小文字が違っても同一と解釈するため
12.saveされたときにメールアドレスが小文字になっているかテスト
※reloadメソッド:データベースの値に合わせて更新する(インスタンスをデータベースから再取得する)
また、!を使用してbefore_saveコールバックを編集
※!=属性を直接変更(破壊的メソッド)
ここまでで、userモデルに関してのバリデーションの設定を終了
次に進む(^^)/