【发布时间】:2014-03-06 22:51:55
【问题描述】:
假设我有属于Project 的Projects 和People。 Person 可以是领导者,也可以不是领导者,并且有这个范围。一个Project必须至少有一个leader,否则无效。所以我尝试了这个:
class Project < ActiveRecord::Base
has_many :people
validate :has_a_leader
def has_a_leader
unless self.people.lead.size > 0
puts 'Must have at least one leader'
errors.add(:people, 'Must have at least one leader')
end
end
end
class Person < ActiveRecord::Base
belongs_to :project
scope :lead, -> { where(:is_lead => true) }
end
不幸的是,验证仅适用于已保存的记录,因为新记录的范围始终为空:
p = Project.new
p.people.build(:is_lead => true)
=> #<Person ..., is_lead: true>
p.people
=> #<ActiveRecord::AssociationRelation [#<Person ..., is_lead: true>]>
p.people.lead
=> #<ActiveRecord::AssociationRelation []>
p.valid?
'Must have at least one leader'
=> false
另一种语法的尝试:
p = Project.new
p.people.lead.build
=> #<Person ..., is_lead: true>
p.people.lead
=> #<ActiveRecord::AssociationRelation []>
p.people
=> #<ActiveRecord::AssociationRelation []> # <-- first syntax at least got something here
p.valid?
'Must have at least one leader'
=> false
所以看起来我必须像这样重写验证并在创建新项目时使用第一种语法:
def has_a_leader
unless self.people.find_all(&:is_lead).size > 0
puts 'Must have at least one leader'
errors.add(:people, 'Must have at least one leader')
end
end
但现在我有两个地方定义了领导者是什么:验证方法和范围 lambda。我重复自己。有效,但不是 Rails 方式。
有没有更好的方法来做到这一点?
【问题讨论】:
标签: ruby-on-rails validation ruby-on-rails-4 rails-activerecord has-many