はじめに
こんにちは、waruby510です。
今回、初めてQiitaへの記事を投稿させていただきます。
最近、色んな方の記事に助けてもらってばかりの状況なので、
備忘録&同じ初学者の力になれる内容 を簡単にですが、記事にしてみました。
内容は、タイトル通りですが、
validatesメソッドのonオプションを使って、バリデーションのタイミングを指定してみた
と言う感じです。
もちろん経験者にとっては、かなりイージーな内容になっています。初心者目線でこの記事を書いていますので、ご了承ください。
また、あまり奥深いところまでは書いていないので、今後更新していければと思います。
<補足>
※初心者の立場で記事を書いています。最低限の下調べと実際に動くかどうかは確認していますが、もし誤った内容を記載していた場合は、ご指摘いただければと思います。
※まだまだ文章を書くことに慣れていません。読みにくいかもしれませんが、どうかお付き合いください。
##開発環境
Rails バージョン5.2.2
ruby バージョン2.5.3
※ログイン機能等に関しては、gemのdeviseは使っていません。
アプリケーション詳細
- ユーザー登録・編集機能 ← 今回の記事の問題箇所
- 画像投稿、編集、削除機能 & いいね機能
簡単に言うと、インスタのようなアプリです。
発生した問題
ユーザー編集機能を追加した時にある問題に差し掛かりました。
それは、ユーザー編集画面にてパスワード欄を無くしたはずなのに、バリデーションがかかってしまう問題。
仕方なく、編集画面にもパスワード入力欄を設けて対応しましたが、
ユーザー目線で考えたら、使いにくいの一言。
実際、userモデルに対しては、以下のようなバリデーションを追加していました。
class User < ApplicationRecord
#名前とメールアドレスに対するバリデーション
validates :name, presence: true, length: {maximum: 30}
validates :email, presence: true, length: {maximum: 255},format: { with: /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i },uniqueness: true
#略
#パスワードをハッシュ化
has_secure_password
#パスワードに対するバリデーション
validates :password, presence: true, length: {minimum: 6}
#略
end
考えられる原因
バリデーションのデフォルトでは、レコードの作成時、更新時。つまり保存が促されるときに実行されるように設定されている。つまり、編集時にパスワードがないとバリデーションがかかってしまいます。
冷静に考えてみると、ただ編集画面のパスワード欄の表示を消しているだけなので、バリデーションがかかるのも当たり前ですよね。笑
考えれる対応策としては、バリデーションのかかるタイミングを指定できれば解決できそう。
実際にやったこと
Userモデルのpasswordカラムに対して、on: :create
を追加
#on: :create を追加
validates :password, presence: true, length: {minimum: 6}, on: :create
ここでようやくon
オプションの登場です。
ここまで、長々と書いてきましたが、たったこれだけです......笑
バリデーションのタイミングを特定して実行したい場合、on: メソッド名
とオプションを追加することで、そのアクションの時のみバリデーションを実行することができるみたいです。
今回は、ユーザー登録時のみパスワードのバリデーションを起動させたいので、on: :create
とします。
もしメソッド名をon: update
にすれば、編集の更新時のみバリデーションがかかるという仕組みなのです。
個人的には結構使いそうな予感。
今回は、RailsGuideの下記リンクを参考にしました。
参考リンク: RailsGuide
3.4 :on
:onオプションは、バリデーション実行のタイミングを指定します。ビルトインのバリデーションヘルパーは、デフォルトでは保存時に実行されます。これはレコードの作成時および更新時のどちらの場合にも行われます。バリデーションのタイミングを変更したい場合、on: :createを指定すればレコード新規作成時にのみ検証が行われ、on: :updateを指定すればレコードの更新時にのみ検証が行われます。
class Person < ApplicationRecord # 値が重複していてもemailを更新できる validates :email, uniqueness: true, on: :create
新規レコード作成時に、数字でない年齢表現を使用できる
validates :age, numericality: true, on: :update
デフォルト (作成時と更新時のどちらの場合にもバリデーションを行なう)
validates :name, presence: true
end
実際に、編集画面の動作を確認してみました。
見事にパスワードに対するバリデーションが回避されています。
少しはユーザー目線の機能に近づけた気がします。
今の自分の良いところは、初心者ということもあり、ユーザー目線に近い状態で開発ができるということ。この目線は今後も大事にしていきたいと思います。
さいごに
結論が呆気なくて、すみませんでした。
自分自身もこれだけ?っていう感じでしたが、とてもいい勉強になりました。
ただ、まだまだ便利な使い方が間違いなくあるはずなので、これから学習していく中で整理していき、また記事にできればと思います。
ここまで読んでくださった方、本当にありがとうございます。
今回は、初めてということもあり、Markdown記法に慣れるために色々な記法を使って書いてみました。そのため、無駄に記事が長くなってしまいましたが、個人的にはかなりいい練習ができたと思います。
この記事が誰かのお役に立てれれば本望です。
以上です。