【问题标题】:Nested model error messages嵌套模型错误消息
【发布时间】:2011-08-13 12:58:48
【问题描述】:

我正在使用 Ruby on Rails 3.0.9,并且正在尝试验证嵌套模型。假设我为“主”模型运行验证并为嵌套模型生成一些错误,我得到以下结果:

@user.valid?

@user.errors.inspect
# => {:"account.firstname"=>["is too short", "can not be blank"], :"account.lastname"=>["is too short", "can not be blank"], :account=>["is invalid"]}

您如何看到 RoR 框架创建了一个具有以下键的 errors 哈希:account.firstname、account.lastname、account。因为我想通过使用涉及 CSS 属性的 JavaScript(顺便说一句:我使用 jQuery)处理那些错误键\值对来在前端内容上显示错误消息,所以我想“准备”该数据并将这些键更改为 @ 987654326@、account_lastname、account(注意:我将. 替换为_ 字符)。

如何将键值从例如account.firstname 更改为account_firstname?

而且,最重要的是,我应该如何处理这种情况?我正在尝试做一个“好”的方法来处理嵌套模型错误吗?如果不是,那么常见的\最佳方法是什么?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 validation model


    【解决方案1】:

    我做了一个快速关注,它显示了嵌套模型的完整错误消息:

    https://gist.github.com/4710856

    #1.9.3-p362 :008 > s.all_full_error_messages
      # => ["Purchaser can't be blank", "Consumer email can't be blank", "Consumer email is invalid", "Consumer full name can't be blank"]
    

    【讨论】:

      【解决方案2】:

      对 Rails 错误哈希进行一些创造性的修补可以帮助您实现目标。在config/initalizers 中创建一个初始化器,将其命名为errors_hash_patch.rb 并将以下内容放入其中:

      ActiveModel::Errors.class_eval do
        def [](attribute)
          attribute = attribute.to_sym
          dotted_attribute = attribute.to_s.gsub("_", ".").to_sym
          attribute_result = get(attribute)
          dotted_attribute_result = get(dotted_attribute)
          if attribute_result 
            attribute_result 
          elsif dotted_attribute_result
            dotted_attribute_result
          else
            set(attribute, [])
          end
        end
      end
      

      您在这里所做的只是简单地覆盖访问器方法[] 以更努力地尝试。更具体地说,如果您要查找的键有下划线,它将尝试按原样查找,但如果找不到任何内容,它也会用点替换所有下划线并尝试查找。除此之外,该行为与常规的[] 方法相同。例如,假设您有一个错误哈希,类似于您的示例中的哈希:

      errors = {:"account.firstname"=>["is too short", "can not be blank"], :"account.lastname"=>["is too short", "can not be blank"], :account=>["is invalid"]}
      

      以下是您可以访问它的一些方法以及返回的结果:

      errors[:account] => ["is invalid"]
      errors[:"account.lastname"] => ["is too short", "can not be blank"]
      errors[:account_lastname] => ["is too short", "can not be blank"]
      errors[:blah] => []
      

      我们不会更改密钥在错误哈希中的存储方式,因此我们不会意外破坏可能依赖于哈希格式的库和行为。我们所做的只是在我们如何访问散列中的数据方面变得更聪明一些。当然,如果您确实想更改散列中的数据,模式是相同的,您只需要覆盖 []= 方法,并且每次 rails 尝试存储带有点的键时,只需将点更改为下划线。

      关于您的第二个问题,尽管我已经向您展示了如何按照您的要求进行操作,但总的来说,最好尝试遵守 rails 尝试做事的方式,而不是尝试将 rails 弯曲到您的将要。在您的情况下,如果您想通过 javascript 显示错误消息,大概您的 javascript 将可以访问错误数据的散列,那么为什么不使用 javascript 调整此数据以采用您需要的格式。或者,您可以在控制器中克隆错误数据并在那里调整它(在您的 javascript 访问它之前)。在不了解您的情况(您如何编写表单,您的验证 JS 到底要做什么等)的情况下,很难给出建议,但这些是一些一般准则。

      【讨论】:

        【解决方案3】:

        我在使用 AngularJs 时遇到了同样的问题,因此我决定在名为 active_model_errors.rb 的初始化程序中覆盖 ActiveModel::Errors 类的 as_json 方法,以便它可以替换 . 的 _

        这里是初始化代码:

        module ActiveModel
          class Errors
            def as_json(options=nil)
              hash = {}
              to_hash(options && options[:full_messages]).each{ |k,v| hash[k.to_s.sub('.', '_')] = messages[k] }
              hash
            end
          end
        end
        

        希望对大家有帮助

        【讨论】:

          【解决方案4】:

          我不确定,但我认为你无法在没有痛苦的情况下改变这种行为。但是您可以尝试http://bcardarella.com/post/4211204716/client-side-validations-3-0

          之类的解决方案

          【讨论】:

          • 感谢您的回答,但对于这类事情,我想专门使用 Ruby on Rails 框架。
          猜你喜欢
          • 1970-01-01
          • 2012-02-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-09-26
          • 2016-01-06
          • 1970-01-01
          相关资源
          最近更新 更多