Ruby on rails 验证嵌套在动态生成字段中的动态生成字段

Ruby on rails 验证嵌套在动态生成字段中的动态生成字段,ruby-on-rails,validation,ruby-on-rails-4,rails-activerecord,cocoon-gem,Ruby On Rails,Validation,Ruby On Rails 4,Rails Activerecord,Cocoon Gem,我有三种模式:Company,Person和Role一家公司有很多:人,一个人有很多:角色,而一家公司,有很多:角色,通过::人。有趣的是:一个公司的人数和一个人的角色都是使用cocoon分配的,这意味着我在一组动态生成的字段中有一组动态生成的字段 我遇到的问题是如何确认公司的角色。例如,每个公司都需要一位总裁(role.role\u name=“President”),因此我设置了以下内容:验证: validate :final_incorporation def company_valid

我有三种模式:
Company
Person
Role
一家公司
有很多:人
,一个人
有很多:角色
,而一家公司,
有很多:角色,通过::人
。有趣的是:一个公司的人数和一个人的角色都是使用cocoon分配的,这意味着我在一组动态生成的字段中有一组动态生成的字段

我遇到的问题是如何确认公司的角色。例如,每个公司都需要一位总裁(
role.role\u name=“President”
),因此我设置了以下内容:验证:

validate :final_incorporation

def company_validation
    errors.add(:company, "needs a president") if self.roles.where(role_name: "President").count==0
end
…而且很有效。。。有时候。如果我注释掉验证并将公司连同人员和角色一起保存到数据库中,然后将验证放回并保存它。它通过了验证

但是,如果我添加一个人,然后为该人添加一个“总统”角色,并尝试提交验证,则不会通过

我的猜测是,尽管我不知道如何解决这个问题,但给每个生成的字段分配临时id的方法正在破坏验证中指定的关联

所以从日志中:

这通过了验证:

 ..."people_attributes"=>{"0"=>{"fname"=>"test", "lname"=>"", "roles_attributes"=>{"0"=>{"role_name"=>"President", "_destroy"=>"false", "id"=>"5"}, "1"=>{"role_name"=>"Treasurer", "_destroy"=>"false", "id"=>"6"}}}...
但这并不是:

..."people_attributes"=>{"1455189047186"=>{"fname"=>"test", "lname"=>"", "roles_attributes"=>{"1455189059602"=>{"role_name"=>"President", "_destroy"=>"false"}, "1455189066001"=>{"role_name"=>"Treasurer", "_destroy"=>"false"}}...
编辑这也不会通过验证(以前保存的人员,但添加了角色)


任何关于如何解决这个问题的想法都将不胜感激。提前谢谢

所以问题是,既然你正在创建一个新的
角色
,它就没有意识到你的
员工
担任
总裁
?@RichardPeck我只是重新阅读了你的问题,我不确定这是不是真的。问题是,当我(使用cocoon)添加一个
,然后向该人添加一个
角色
(也使用cocoon),然后使新添加的角色成为“总统”时,它不会通过验证。(除非我先通过禁用验证来保存它,然后尝试将其提交进行验证。这样就可以了。)因此,您正在创建一个新角色,或者使用数据库中已有的角色?避免使用sql的角色工作得非常好(涉及范围等的方法遇到了相同的问题)。我的目标不是执行db查询。我只是对扫描提交的数据寻找“总统”角色感兴趣。我不应该担心人数;在大多数情况下,使用此表单时不超过10次。谢谢这么说这很有效?(我刚出局,错过了比赛)@RichardPeck第二种方法似乎很有效。这是一个多一点的手册(与小循环在最后)比我预期的,但没有关系。抱歉混淆你。我编辑了我的答案,现在应该可以用了,但它很难看,效率也很低。希望尼安德特斯洛能想出更好的办法:)不用担心:)我很高兴能帮上忙。
def company_validation
    errors.add(:company, "needs a president") unless people.any?{|person| person.roles.any?{|role| role.role_name == "President" && !role.marked_for_destruction?}}
end
def company_validation
    errors.add(:company, "needs a president") unless people.any?{|person| person.roles.any?{|role| role.role_name == "President" && !role.marked_for_destruction?}}
end