Rails勉強ログ#2 バリデーションの設定
今日もがっつりアプリの実装練習をしてきましたので、ログを残していきます。
ユーザーモデルにバリデーションを設定する
やりたいこと
新しく作るサイトで、ユーザー新規登録の操作に対してバリデーションをかけたい。
バリデーションとは?
Webサイトで会員登録をする際に、
パスワードは大文字・小文字・英数字を含めてください!
氏名(カナ)は全角カタカナで入力してください!
など出てくるアレ。
要は「受け付ける文字種に縛りを入れる」こと。
コード例
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
with_options presence: true do
validates :nickname
validates :name, format: { with: /\A[ぁ-んァ-ヶ一-龥々ー]+\z/, message: "全角ひらがな、全角カタカナ、漢字で入力して下さい" }
validates :name_katakana, format: { with: /\A[ァ-ヶー-]+\z/, message: "全角カタカナで入力して下さい" }
validates :birthday
end
PASSWORD_REGEX = /\A(?=.*?[a-z])(?=.*?[\d])[a-z\d]+\z/i.freeze
validates_format_of :password, with: PASSWORD_REGEX, message: 'パスワードには英字と数字の両方を含めてください'
end
解説
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
この部分はdeviseを使ってuserモデルを作ったらデフォルトで入っている各種設定。詳しいことはまだ知らない。
userモデルの各カラムへの設定
with_options presence: true do
validates :nickname
validates :name, format: { with: /\A[ぁ-んァ-ヶ一-龥々ー]+\z/, message: "全角ひらがな、全角カタカナ、漢字で入力して下さい" }
validates :name_katakana, format: { with: /\A[ァ-ヶー-]+\z/, message: "全角カタカナで入力して下さい" }
end
まず1行目の、with_options presence:true do~end で囲まれているところは、
「 nickname, name, name_katakana, birthday には必ずデータを入れてね。空白は受け付けないよ」という意味。
全部のカラムに presence: true を書かなくてすむのでコードがコンパクトになる。
ただ、とにかく使えば良い!というわけでもないようで、
Claude3に聞いたところ以下の回答が得られた。
正規表現による文字種の指定
validates :name, format: { with: /\A[ぁ-んァ-ヶ一-龥々ー]+\z/, message: "全角ひらがな、全角カタカナ、漢字で入力して下さい" }
validates :name_katakana, format: { with: /\A[ァ-ヶー-]+\z/, message: "全角カタカナで入力して下さい" }
ここは「正規表現」という書き方を使って、
「名前にはかな・カナ・漢字が使えます」
「フリガナはカタカナでよろしく」
ということを表現している。
ユーザーが決まりを守らないと message: に定義したエラーメッセージを返す。
正規表現は、「正規表現であること自体を示す枠組みを担う文字」と「正規表現で表される中身の文字」が羅列されるので、一見理解不能な呪文に見える。というか、今でも脳が理解を拒んでいる感はある。
まぁ、いざ使うときはググればよいので
「指定したい文字種によって、専用の呪文がある」くらいの認識でも、一応実装はできそう。
パスワードのバリデーション
最近は、パスワードに文字種の制限がかかっているサイトが増えた。
たとえばパスワードの文字種に「英数混合必須」の制限をかける呪文はこちら。freezeをくっつけることで改変を防止している。
PASSWORD_REGEX = /\A(?=.*?[a-z])(?=.*?[\d])[a-z\d]+\z/i.freeze
validates_format_of :password, with: PASSWORD_REGEX, message: 'パスワードには英字と数字の両方を含めてください'
でも、これは上述の通り、「英数混合」の条件しかない。
そして、最低文字数はdevise標準の「6文字以上」。
たとえば、6文字のPWは ( 26+10 ) ^ 6 で2,176,782,336通りしか存在せず、すぐに解読されてしまう。たぶん。
もっとつよいパスワードを必須にしてみよう
PASSWORD_REGEX = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/.freeze
validates_format_of :password, with: PASSWORD_REGEX, message: 'パスワードには大文字・小文字・数字・記号をすべて含めて8文字以上にしてください'
どうでしょうか。
8文字以上の英数必須、大文字小文字必須、記号も必須。
これなら( 26 + 26 + 10 + 7 ) ^ 8 = 513,798,370,000,000 パターンぐらい?あるので、まぁ大丈夫でしょう。
(そもそも二要素認証の時代に、PWの強さだけで勝負するのはどうなの?…みたいな話はここでは割愛 というかそもそもパスワードに制限をかけたい、という話でした)
まとめ
バリデーションとは、「文字の種類を限定」したり、「空欄を許可しない」などの設定。
文字種を制限するには、「正規表現」という手法をつかって許可する文字を指定する。
パスワードの指定には、専用の呪文を使う。
備忘録おわり。
この記事が気に入ったらサポートをしてみませんか?