【问题标题】:Validating dynamically generated fields nested within a dynamically generated field验证嵌套在动态生成的字段中的动态生成的字段
【发布时间】:2016-02-11 11:59:43
【问题描述】:

我有三个模型ComapnyPersonRole 一个公司has_many :people、一个人has_many :roles 和一个公司has_many :roles, through: :people。有趣的地方在于:一个公司的人数和一个人的角色是使用 cocoon 分配的,这意味着我在一组动态生成的字段中拥有一组动态生成的字段。

我遇到的问题是验证公司的角色。比如每家公司都需要一个总裁(role.role_name="President")所以我设置如下:validation:

validate :final_incorporation

def company_validation
    errors.add(:company, "needs a president") if self.roles.where(role_name: "President").count==0
end

...它的工作原理! ...有时。如果我注释掉验证并将公司与人员和角色一起保存到数据库中,然后将验证放回并保存。它通过了验证。

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

我的猜测,虽然我不知道如何绕过它,但 cocoons 为每个生成的字段分配一个临时 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"}}...

编辑这也没有通过验证(之前保存的人,但添加了角色)

..."people_attributes"=>{"0"=>{"fname"=>"test", "lname"=>"", "roles_attributes"=>{"1455195637658"=>{"role_name"=>"President", "_destroy"=>"false"}, "1455195641046"=>{"role_name"=>"Treasurer", "_destroy"=>"false"}}...

任何有关如何解决此问题的想法将不胜感激。提前致谢!

【问题讨论】:

  • 所以问题是,既然您正在创建一个新的Role,它没有认识到您的任何people 具有President 的角色?
  • @RichardPeck 我刚刚重读了你的问题,但我不确定是不是这样。问题是,当我(使用 cocoon)添加 Person,然后向那个人(也使用 cocoon)添加 Role,然后将新添加的角色设为“总统”时,它没有通过验证。 (除非我先通过禁用验证来保存它,然后尝试提交它进行验证。然后就可以了。)
  • 那么您是在创建一个新角色,还是使用数据库中已有的角色?

标签: ruby-on-rails validation ruby-on-rails-4 rails-activerecord cocoon-gem


【解决方案1】:
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

【讨论】:

  • 避免使用sql的方法效果很好(涉及范围等的方法也遇到了同样的问题)。无论如何,我的目标不是执行数据库查询。我只是对扫描提交的数据以寻找“总统”角色感兴趣。我不应该担心人数;大多数情况下,使用此表格时不超过 10 个。谢谢!
  • 所以这很好用吗? (我刚出去,错过了动作)
  • @RichardPeck 第二种方法似乎是。它比我预期的要手动一些(最后有一个小循环),但没关系。
  • 很抱歉让您感到困惑。我编辑了我的答案,它现在应该可以工作了,但它非常丑陋且效率低下。希望 neanderslob 会想到更好的东西:)
  • 别担心 :) 很高兴能帮上忙。
猜你喜欢
  • 2021-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多