はじめに
知人がemailの正規表現を使ったバリデーションを自ら作成して設定しようとした際、うまく設定を反映させられませんでした
いろいろ調べたところRailsのバリデーションやらdeviseのバリデーションやらが絡んでいたためでした
今まで知らないで使ってたことなど勉強になったことが多かったので整理してまとめておきます
対象読者
- form_withやform_forが何かをなんとなく理解している人
- バリデーションが何かをなんとなく理解してる人
環境
- Ruby: 2.5.1
- Rails: 5.2.3
状況
- 正規表現で~@~.~という形じゃないとアドレスとして登録できないようなカスタムバリデーションを作成した
- そのバリデーションを有効にしたが、下記の画像のような謎のバリデーションにひっかかった
自分で作ったカスタムバリデーションじゃないのがでてきた。。。ってなったんですが
結論、Railsのバリデーションとdeviseのバリデーションを解除してやれば、目的通り自作のカスタムバリデーションのみ反映させられました
以下に、やり方と解説を記載します
Railsのバリデーション設定
Railsでメールアドレスやパスワードをユーザーに入力させるとき、入力フォームを作成するためにform_forやform_withを使いますよね。こんな感じで
= form_with(model: @user, local: true, class: 'hoge') do |form|
= form.label :email, 'メールアドレス'
= form.email_field :email
ここで記載したemail_fieldがさっきのバリデーションの正体です
このように記載することでRailsはこの入力フォームをemailだと認識して、簡単なバリデーションを自動でかけるようになっているみたいです
なので先ほどの記載を以下のように書き換えるとRails側でバリデーションをかけないようにできます
#変更前
= form.email_field :email
#変更後
= form.text_field :email
結果がこちら
先ほどのバリデーションは消えましたが、フラッシュメッセージにバリデーションが2つ出てきてしまいました
deviseのバリデーション設定
今のままだとバリデーションが2つ出てきてしまいます。先ほどの画像の左側がdeviseのバリデーション、右側が自分で設定したカスタムバリデーションです
今回は自分が設定したカスタムバリデーションだけ表示させたいので、deviseのバリデーション設定を解除します
通常、deviseをインストールした場合、モデル内に下記のような記述があると思います
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
この:validatableがdeviseのバリデーションなので、この記述を消します
devise :database_authenticatable, :registerable,
:recoverable, :rememberable
これでdeviseのデフォルトのバリデーションも解除できました
結果はこちら
ちゃんと自分で設定したバリデーションだけが適用されていますね
*カスタムバリデーションの作成の仕方は最後の参考URLに載せておきます
まとめ
- Railsのemail_fieldではメールアドレス用の簡単なバリデーションをかける仕様になっている
- deviseではデフォルトで簡単なバリデーションをかけるようになっている
- バリデーションの優先順位はemail_field > devise, カスタム(自作)
- カスタムバリデーションのみ適用させる場合は、text_fieldを使い、deviseの:validatableを削除する
Railsもdeviseも知らないところで色々と機能してくれてますが、少しずつそういう部分を理解していくことで、色々応用できそうですね
特にdeviseは便利ですが、意味を理解していないで使っている部分が多いと思ったので今回のようなケースはかなり勉強になりました
余談ですが、password_fieldは入力した文字を"●"で秘匿化してくれてます
間違いなどがあれば指摘していただけると助かります
少しでも参考になった、勉強になったという方がいらっしゃれば幸いです
参考URL
自作のカスタムバリデーションを作成する方法