はじめに
バリデーションを記載するときはvalidates
を使用してきてvalidate do ... end
の書き方を知らなかったので記載
validates と validate の違いについて
validatesメソッド・・・事前に定義されたバリデーションオプションを使用して検証ルールを指定する
validateメソッド・・・カスタムなバリデーションロジックを自由に記述する
validatesについて詳しく
・複数のバリデーションルールを一度に指定するために使用される
・モデルクラス内で使用され、属性の検証ルールを定義
・バリデーションルールはハッシュ形式で指定され、属性名とバリデーションオプション(プレゼンス、長さ、一意性など)を組み合わせて指定する
実際の使い方
class User < ApplicationRecord
validates :name, presence: true
validates :email, presence: true, uniqueness: true
end
上記の例では、name属性が存在すること、email属性が存在し、かつ一意であることを検証している。validatesメソッドは、複数の属性とそのバリデーションルールをまとめて指定するための便利な方法。
validateについて詳しく
・カスタムなバリデーションロジックを定義するために使用される
・個別のメソッドとしてモデルクラス内に定義され、特定のバリデーション処理を行う
・validateメソッド内でカスタムなバリデーションコードを記述することができる
実際の使い方
単一の属性のカスタムバリデーション
class User < ApplicationRecord
validate :custom_validation
def custom_validation
if age < 18
errors.add(:age, "must be at least 18")
end
end
end
Userモデルのcustom_validationメソッドを定義。このメソッド内で、age属性が18未満の場合にエラーメッセージを追加している。
複数の属性を使用したカスタムバリデーション
class User < ApplicationRecord
validate :custom_validation
def custom_validation
if age < 18
errors.add(:age, "must be at least 18")
end
end
end
Userモデルのcustom_validationメソッド内で、start_dateとend_date属性の関係性を検証。もしstart_dateが存在し、end_dateが存在し、かつstart_dateがend_dateよりも後の場合、エラーメッセージを追加する。
複数の属性を使用したカスタムバリデーション(モデル間の関連を検証)
class Order < ApplicationRecord
belongs_to :user
validate :validate_user_credit_limit
def validate_user_credit_limit
if user.present? && total_amount > user.credit_limit
errors.add(:base, "Exceeded user's credit limit")
end
end
end
Orderモデルのvalidate_user_credit_limitメソッド内で、ユーザーのクレジット限度額を超える注文を検証。userが存在し、かつtotal_amountがユーザーのクレジット限度額を超える場合、エラーメッセージを追加する。
validate使用時のエラーメッセージ追加方法
validate使用時はerrors.addメソッドを使用して自分でエラーメッセージを追加することで、バリデーションエラーが発生したことを示す。
errorsメソッド
errorsメソッド・・・モデルのエラーオブジェクト(ActiveModel::Errorsクラスのオブジェクト)を返す
addメソッド
エラーオブジェクトのaddメソッド・・・モデルのオブジェクトにバリデーションエラーを登録する
errors.add(:base, "Exceeded user's credit limit")
第一引数:属性名のシンボル
第二引数:エラーメッセージ
※第2引数には直接メッセージ指定だけでなく、:empty :invalidなどの既存のものや、開発者自身が決めた任意のシンボルも指定できる
errors.add(:expired_at, :expired_at_too_old)
ja:
activerecord:
models:
~省略~
errors:
messages:
expired_at_too_old: は掲載開始日より新しい日時にしてください。