Expiry_dateという属性を含むActive Recordモデルがあります。今日(現在の日付)以降になるように検証するにはどうすればよいですか? Rails and Rubyにまったく新しいのですが、これに正確に答える同様の質問が見つかりませんでしたか?
私はRails 3.1.3およびRuby 1.8.7
あなたの質問は(ほとんど)正確に答えられます Railsガイド で。
ここに彼らが与えるサンプルコードがあります。このクラスは、日付がpastにあることを検証しますが、質問は、日付がfutureにあることを検証する方法ですしかし、それを適応させるのは非常に簡単です:
class Invoice < ActiveRecord::Base
validate :expiration_date_cannot_be_in_the_past
def expiration_date_cannot_be_in_the_past
if expiration_date.present? && expiration_date < Date.today
errors.add(:expiration_date, "can't be in the past")
end
end
end
カスタムバリデーターを設定するコードは次のとおりです。
#app/validators/not_in_past_validator.rb
class NotInPastValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
if value.blank?
record.errors.add attribute, (options[:message] || "can't be blank")
elsif value <= Time.zone.today
record.errors.add attribute,
(options[:message] || "can't be in the past")
end
end
end
そしてあなたのモデルでは:
validates :signed_date, not_in_past: true
@dankohnの回答を取得し、I18nに対応するように更新しました。 blank
テストも削除しました。これはこのバリデーターの責任ではなく、validates呼び出しにpresence: true
を追加することで簡単に有効にできるためです。
in_future
という名前の更新されたクラスは、not_in_past
よりも優れていると思います
class InFutureValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
record.errors.add(attribute, (options[:message] || :in_future)) unless in_future?(value)
end
def in_future?(date)
date.present? && date > Time.zone.today
end
end
ローカリゼーションファイルにin_future
キーを追加します。
errors.messages.in_future
の下のすべてのフィールド、たとえばオランダ語の場合:
nl:
errors:
messages:
in_future: 'moet in de toekomst zijn'
または、activerecord.errors.models.MODEL.attributes.FIELD.in_future
の下のフィールドごと、たとえばオランダ語のVacancy
モデルのend_date
の場合:
nl:
activerecord:
errors:
models:
vacancy:
attributes:
end_date:
in_future: 'moet in de toekomst zijn'
Rails 4+にはfuture?
およびpast?
メソッドはDateTime
オブジェクトのため、より簡単な答えは
class Invoice < ActiveRecord::Base
validate :expiration_date_cannot_be_in_the_past
def expiration_date_cannot_be_in_the_past
if expiration_date.present? && expiration_date.past?
errors.add(:expiration_date, "can't be in the past")
end
end
end
最も単純で実用的なソリューションは、Railsの組み込み検証を使用することです。次のように検証するだけです:
validates :expiry_date, inclusion: { in: (Date.today..Date.today+5.years) }