Ruby on rails 在Rails中,如何验证作用域为过去6个月的:字段的唯一性

Ruby on rails 在Rails中,如何验证作用域为过去6个月的:字段的唯一性,ruby-on-rails,validation,Ruby On Rails,Validation,第一项 在将字段保存到数据库之前,我希望验证该字段以确保其唯一性(在过去6个月内) 我想我应该使用validates\u university\u of:field,区分大小写=>false,Scope=> 对于我的应用程序,只有当它被使用时才必须是唯一的您可能可以这样做: def validate errors.add(:field, 'blah blah') if is_used_recently && !has_unique_field? end def has

第一项
在将字段保存到数据库之前,我希望验证该字段以确保其唯一性(在过去6个月内)

我想我应该使用validates\u university\u of:field,区分大小写=>false,Scope=>


对于我的应用程序,只有当它被使用时才必须是唯一的您可能可以这样做:

def validate
    errors.add(:field, 'blah blah') if is_used_recently && !has_unique_field? 
end

def has_unique_field?
    Model.exists?(['field = ? and created_at > ?', self.field, 6.months.ago])
end 

def is_used_recently
    self.created_at < 6.months.ago || self.new? # i don't know if created_at would be set by this point
end

我希望这有帮助,如果我犯了任何错误,请告诉我

通过检查给定范围内是否已存在具有给定字段相同值的记录,验证
的唯一性
:scope
用于定义唯一性的范围(显然);例如,如果我正在创建博客软件,并且只允许每个博客使用一次文章标题,我可以说
验证:title的唯一性,:scope=>:blog\u id
——如果没有范围,我只允许每个标题在整个系统中使用一次<代码>:scope不允许您执行复杂的检查,就像您希望的那样

您可能需要做的是创建您自己的验证函数,以在给定的时间范围内检查相关字段的唯一性(代码在模型中):


在上面的块中,
record
是正在验证的记录,
attr
是属性(因此
field1
field2
,等等),而
value
是该属性的值。

我不认为您最近使用的属性对给定的字段有效,因为在创建新记录时,self.created_at<6.months.ago==true,但您可以在6个月前创建第二条记录,其值与:fieldAh相同。我把问题看错了。。。我会更新我的答案。谢谢你提供的关于清理空白的信息,因为我在很多字段中都使用了这个,所以我试图通过将一些字段设置为字段数组并循环通过它们来让它更干燥,但是如果我保留self.variable\u name,如果我删除self,它就不知道变量名称是什么。从前面看,它确实知道,但不适用于现场。我知道我错过了一些简单的事情。但是不知道如何解决:(你可以通过属性散列访问属性:fields.each{f | self.attributes[f].strip!}抱歉仍然卡住了\n类通讯before_validation :clean_up_whitespace def clean_up_whitespace self.some_field.strip! # this does the strip in place end
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
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