validates_uniqueness_of
работает, проверяя, существует ли уже запись с таким же значением данного поля в данной области видимости. :scope
позволяет вам определить сферу (очевидно) уникальности; например, если бы я создавал программное обеспечение для блога и хотел, чтобы заголовок сообщения использовался только один раз для каждого блога, я мог бы сказать validates_uniqueness_of :title, :scope => :blog_id
- без рамок я бы разрешил использовать каждый заголовок только один раз для вся система. :scope
не позволит вам сделать сложную проверку, такую, как вы хотите.
Что вам, вероятно, нужно сделать, - это создать собственную функцию проверки для проверки уникальности рассматриваемого поля в течение заданного периода времени (код входит в модель):
validate :field_must_be_unique_within_six_months
def field_must_be_unique_within_six_months
return if field.blank?
num_duplicates = self.class.count(:conditions => ["field = ? AND created_at < ?", self.field, 6.months.ago])
if num_duplicates > 0
errors.add(:field, :taken)
end
end
Метод field_must_be_unique_within_six_months
будет работать аналогично validates_uniqueness_of
в том смысле, что он добавит сообщение об ошибке, если уже существует запись с таким же заданным полем, но с добавленным условием, что он также проверит дату. validate :field_must_be_unique_within_six_months
добавит метод в процесс проверки при сохранении записи.
Чтобы проверить несколько полей одновременно, не нарушая DRY, вы можете использовать validates_each , чтобы сделать что-то вроде следующего:
validates_each :field1, :field2 do |record, attr, value|
if record.class.exists?(["#{attr.to_s} = ? AND created_at < ?", value, 6.months.ago])
errors.add(attr, :taken)
end
end
В приведенном выше блоке record
- это проверяемая запись, attr
- это атрибут (поэтому field1
, field2
и т. Д.) И value
- это значение этого атрибута.