我有一个active
列的模型,它是一个布尔值。我想验证针对company_id
的所有新添加记录的唯一性,这样只要company_id
设置为active
,我就可以向表中添加任意数量的记录false
到active
。每个company_id
应该只有一个validates :company_id, :uniqueness => { :scope => :active }
条记录。
我怎么写这个?我已经尝试过了:
active
但是,这似乎也会对false
company_id
的唯一组合进行验证(这样我在表格中永远不会有两个active
{{1} }}状态,无论active
是什么) - 上面的验证允许company_id
的两个记录,一个记录active = false
,另一个记录active = true
。一旦这两个记录进入,验证就会阻止其他所有记录。
然后我尝试添加这个:
scope :active, where(:active => true)
但这似乎没有改变验证(与上述相同的问题)。
如何编写此验证,以便只要company_id
为false,我就可以添加同一active
个记录,并且每active = true
只允许一个company_id
}?
答案 0 :(得分:14)
无需使用validates_each
- 仅当您想要通过同一个块传递多个属性时才这样做。只需创建自定义验证:
validate :company_id_when_active
def company_id_when_active
if active? and CompanyTerm.exists? ["company_id = ? AND active = 1 AND id != ?", company_id, id.to_i]
errors.add( :company_id, 'already has an active term')
end
end
答案 1 :(得分:7)
Rails 4+为此提供了更好的解决方案。
validates_uniqueness_of :company_id, conditions: -> { where(active: true) }
答案 2 :(得分:4)
好的,我想我终于搞清楚了。
检查Rails指南导致我validates_each,这使我得到了这个解决方案:
scope :active, where(:active => true)
validates_each :company do |model, attr, value|
active = CompanyTerm.active.where(:company_id => value)
model.errors.add(attr, 'already has an active term') unless active.empty?
end
我不知道这是否是最有效的写作方式,但它有效。我愿意接受任何建议!
答案 3 :(得分:1)
旧主题,但有最简单的解决方案。上面的答案几乎是正确的。您可以使用:if
语句作为关键字:
validates :active, :uniqueness => { :scope => :company_id }, :if => :active
答案 4 :(得分:-2)
validates :company_id, :uniqueness => { :scope => :active } unless Proc.new { self.active }
也许你想打电话给公司
validates :company, :uniqueness => { :scope => :active } unless Proc.new { self.active }
修改强>
基于您的解决方案的答案更有效:
scope :active, where(:active => true)
validates_each :company do |model, attr, value|
model.errors.add(attr, 'already has an active term') if CompanyTerm.active.exists?(:company_id => value)
end