lib/validators/past_validator.rb に次のようなカスタムバリデータがあります。
class PastValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
(record.errors[attribute] << "must be in the past") if value >= Date.today
end
end
次のようにapplication.rbでこれを必要としました:
config.autoload_paths += %W(#{config_root}/lib/validators)
このバリデーターをユーザーと写真の 2 つのモデルで使用したいと考えています。ユーザーには誕生日 (日付) があり、写真には日付属性 'taken_on' があります。どちらも過去のものでなければなりません。
user.rb には、次の行があります。
validates :birthday, allow_nil: true, past: true
誕生日の検証は、ここでは魅力のように機能します。
photo.rb:
def self.new_photo(params)
photo = new(taken_on: (Date.parse params[:taken_on]) )
photo
end
validates :taken_on, presence: true, past: true
「past: true」をコメントアウトすると、これも機能しますが、そうでない場合は NoMethodError が発生します。バックトレースは、その値がバリデーターに設定されていないことを示したので、インタープリターは値がメソッドでなければならないと考え、NoMethodError を返します。しかし、なぜ値が設定されていないのですか?
私はすでにphoto.rbで次のことを試みました:
def self.new_photo(params)
date = Date.parse params[:taken_on]
p date # Gives me a correct instance of Date
photo = new(taken_on: date)
photo
end
validates :taken_on, presence: true, past: true, on: :create
奇妙なことは、写真をインスタンス化するときに検証が既に行われていることです。