How to check model date attribute for a specific range (evaluated at runtime)

I have several models with a date attribute, and for each model I would like to confirm these dates for a given range. Basic example:

validates_inclusion_of  :dated_on, :in => Date.new(2000,1,1)..Date(2020,1,1)

Ideally, I would like to evaluate the date range at runtime using a similar approach, for example named_scope, for example:

validates_inclusion_of  :dated_on, :in => lambda {{ (Date.today - 2.years)..(Date.today + 2.years)}}

The above doesn't work, of course, so what's the best way to achieve the same result?

+5
source share
7 answers

If the validation is the same for each class, the answer is quite simple: put the validation method in the module and mix it in each model, then use validateit to add validation:

# in lib/validates_dated_on_around_now
module ValidatesDatedOnAroundNow
  protected

  def validate_dated_around_now
    # make sure dated_on isn't more than five years in the past or future
    self.errors.add(:dated_on, "is not valid") unless ((5.years.ago)..(5.years.from_now)).include?(self.dated_on)
  end
end

class FirstModel
  include ValidatesDatedOnAroundNow
  validate :validate_dated_around_now
end

class SecondModel
  include ValidatesDatedOnAroundNow
  validate :validate_dated_around_now
end

, , , - :

module ValidatesDateOnWithin
  def validates_dated_on_within(&range_lambda)
    validates_each :dated_on do |record, attr, value|
      range = range_lambda.call
      record.errors.add(attr_name, :inclusion, :value => value) unless range.include?(value)
    end
  end
end

class FirstModel
  extend ValidatesDatedOnWithin
  validates_dated_on_within { ((5.years.ago)..(5.years.from_now)) }
end

class SecondModel
  extend ValidatesDatedOnWithin
  validates_dated_on_within { ((2.years.ago)..(2.years.from_now)) }
end
+6

:

    validates :dated_on, :date => {:after => Proc.new { Time.now + 2.years },
                                   :before => Proc.new { Time.now - 2.years } }
+13

validates :future_date, inclusion: { in: ->(g){ (Date.tomorrow..Float::INFINITY) }

+3

, , validates_inclusion_of :in, include?. :

class DelayedEvalRange
  def initialize(&range_block)
    @range_block = range_block
  end
  def include?(x)
    @range_block.call.include?(x)
  end
end

class FirstModel
  validates_inclusion_of :dated_on, :in => (DelayedEvalRange.new() { ((5.years.ago)..(5.years.from_now)) })
end
+1

, . , , imho.

, , . , , . , , ( : in = > rational_date_range) , .

, . DelayedEvalRange. , - , .

0

:

validate :validate_dob

def validate_dob
  unless age_range.cover?(dob.present? && dob.to_date)
    errors.add(:dob, "must be between %s and %s" % age_range.minmax)
  end
end

, , .

, , , , , , , .

0

Rails. :

validates :dated_on, inclusion: { in: (Date.new(2000,1,1)..Date(2020,1,1)) }

, :

validates :occurred_at, presence: true, inclusion: { in: (Date.new(2000,1,1)..Date(2020,1,1)) }

, , 1.day.ago 1.year.from_now .

0

All Articles