Project
에 속하는 Projects
및 People
이 있다고 가정 해 봅니다. Person
은 리더가 될 수도 있고 그렇지 않을 수도 있으며 이에 대한 범위가 있습니다. Project
에는 최소 한 명의 리더가 있어야하며, 그렇지 않으면 무효입니다. 그래서 나는이 시도 :rails 새로운 레코드 유효 범위
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.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
: 또 다른 구문을 시도
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
그래서이 유효성 검사를 다시 작성하고 새 프로젝트를 만들 때 첫 번째 구문을 사용해야합니다.
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
하지만 이제는 리더가되는 사람을 정의한 위치가 두 곳 있습니다. 유효성 검사 방법과 범위 람다입니다. 나는 나 자신을 반복한다. 작동하지만 Rails 방식은 아닙니다.
더 좋은 방법이 있나요?
답변 해 주셔서 감사합니다. 이렇게하면 리더는 사람으로 나타나지 않습니다 ('project.people'에서). 그러나 이것은 아마도 아무것도 아닌 것보다 낫습니다. 어쩌면이 명료하게하기 위해'Person'의 STI로 새로운'Leader' 클래스를 만들면 될까요? – Markus
두 연관에 모두 'Person'을 추가하려고합니다. 또한'leader ='를 override하여'people <<'을 호출 한 다음'super '로 호출을 전달할 수 있습니다. 나는 "리더"가'사람 '과 다른 행동을하는 것이 아니라면 STI에서 이것을 복잡하게하지 않을 것이다. – coreyward
'project_leader = Person.new (name : 'Corey')'에서'is_lead' 속성이'true'로 설정되어 있지 않습니다. 프로젝트를 저장 한 후에는 리더가 사라집니다. – Markus