Как проверить атрибут даты модели против определенного диапазона (оцененный во время выполнения)

Я услышал этот аргумент также - от людей, которые забыли помещать индекс на их внешние ключи и затем жаловались, что определенные операции были медленными (потому что ограничительная проверка могла использовать в своих интересах любой индекс). Таким образом подвести итог: нет никакого серьезного основания не использовать внешние ключи. Вся современная расположенная каскадом поддержка баз данных удаляет, таким образом...

8
задан Simone Carletti 3 December 2009 в 10:55
поделиться

2 ответа

Если проверка одинакова для каждого класса, ответ довольно прост: поместите метод проверки в модуль и смешайте его с каждой моделью, затем используйте validate для добавления проверки:

# 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
ответ дан 5 December 2019 в 07:11
поделиться

Другое решение - полагаться на тот факт, что 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
ответ дан 5 December 2019 в 07:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: