#カスタムバリデートでバリデーション後編
はじめに
はい、後編です。前回はこちら。
自己満で書いてたら、意外と見てくれている人がいて恐縮です。頑張ります。ンゴンゴ!
では今回は、レコードの複数の属性をバリデートするカスタムバリデーションを説明。
##レコードの複数属性に対するカスタムバリデーション##
前回は個別ということでEachValidator
を継承しましたが、今回はValidator
を継承する方法をご説明。
##ケース説明##
今回は例として、プレミアム会員と、通常会員の場合でかけるべきバリデーションが違う時を考えます。
プレミアム会員様は100文字まで自己紹介文をかけますが、通常会員の財布の紐が硬い方は10文字でしか自己紹介ができないようにします。
##Userモデル##
class User < ApplicationRecord
enum status: {
normal: 0, #通常会員
premium: 1, #プレミアム会員
}
include ActiveModel::Validations
validates_with UserValidator
end
enumで会員の状態を把握してます。status
がnormal
かpremium
かでかけるバリデーションを分岐させます。もちろんこれはUser.rb
に書いても機能します。ですが、その様な条件がどんどん増えてくとUser.rb
がおデブちゃんになってしまいます。痩せさせたいですよね?では、結果にコミットしましょう。
てな訳でバリデーションルールは上述コードを見る通り、UserValidator
に書きます。
validates_withによって呼び出されてます。(validates_withはActiveModel::Validationsをインクルードせんと使えないですのでインクルードしてください。)
class UserValidator < ActiveModel::Validator
def validate(record)
if record.status == 'normal' && record.description.length > 10
record.errors[:description] << '通常会員は10文字以内で自己紹介してください。'
elsif record.status == 'premium' && record.description.length > 100
record.errors[:description] << 'プレミアム会員は100文字以内で自己紹介してください。'
end
end
end
if文が汚い...
ですが、これでモデルはスッキリのままバリデーションがかけました。
前回の記事では個別の属性にバリデーションをかける時のカスタムバリデートを説明しましたが、今回も属性1つじゃねえか!!という方、はい。少しケースがわかりづらかったカモです。ごめんなさい。今回の方法はレコードの複数属性にかけるバリデーションを記述するということを意識してください。全ての属性にvalidate_each
書いて検証するのはめんどくさいですよね?ですからまとまったバリデーションはここに書いてmodelはスッキリさせましょうということです。
##まとめ
具体例のしょぼさが経験のなさを物語ってますね。頑張ります。明日は今回登場したenum
についてご説明します。
便利です。頑張ります。
##参考にしたの
Active Record バリデーション
https://railsguides.jp/active_record_validations.html#%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E3%83%90%E3%83%AA%E3%83%87%E3%83%BC%E3%82%BF
【パーフェクトRails】バリデーションをクラスに分離する
https://waterlow2013.hatenablog.com/entry/2016/10/11/011312