【问题标题】:Rails validation error message not showingRails 验证错误消息未显示
【发布时间】:2022-06-20 03:05:17
【问题描述】:

我正在尝试为我的模型验证添加自定义错误消息。如下图:

validates :cost, numericality: { greater_than_or_equal_to: 0, message: :custom_error }

我的 en.yml 看起来像这样:

en:
  activerecord:
    errors:
      messages:
        custom_error: "some error translation"

从我读过的所有内容来看,应该可以。但是,它仅在某些情况下有效。如果我执行以下操作,它似乎可以工作:

a = Item.new
a.valid? 
 # false
a.errors.messages
 # { :cost=>["some error translation"]}

在救援块中,我发现了该错误并打印了如下所示的消息:

def subtract_costs
  item.cost: -10
  item.valid?
  puts "error: #{item.errors.messages}"
  # Above outputs "error: {:cost=>["some error translation"]}"
rescue StandardError => error
  puts error.message
  # Above outputs "Validation failed:"
end

该消息总是发送给Validation failed: 。有谁知道什么可能导致错误消息为空白?我的项目中没有任何其他本地人或翻译。

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    编辑:我看到这里还有另一个问题。 你的救援块有点混乱。在你的救援块中,你救援的是 Rails 运行时错误,而不是模型验证错误(除非你使用了 #save! 或 #update!,它们通过引发模型验证错误将其转变为运行时错误)。 因此,error 在该上下文中是一个运行时错误,并非旨在携带模型验证错误措辞。

    所以你创造了一种“它不起作用”的情况,但在那种情况下它不应该起作用。这应该更清楚:

    def subtract_costs
      item.cost = -10
      item.valid?
      puts "error: #{item.errors.messages}" # outputs "error: {:cost=>["some error translation"]}"
      puts item.errors.class.name
    rescue StandardError => error
      puts error.message # outputs "Validation failed:"
      puts error.class.name
    end
    
    

    您没有正确查找 EN 语言环境消息。 你会这样做:

    validates :cost,
              numericality: { greater_than_or_equal_to: 0,
                              message: I18n.t('activerecord.errors.messages.custom_error') }
    

    现在有一些方法可以完全避免在验证器上设置消息,但您需要将消息放在正确的位置。 这是您的 EN 语言环境文件中的正确位置/层次结构。这是您的特定消息的正确位置:

    en:
      errors:
        messages:
          greater_than_or_equal_to: 'some error translation'
    

    一般来说,这里是放置自定义验证错误消息(以及我喜欢的措辞)的位置。

    en:
      errors:
        format: "%{message}"
        messages:
          accepted:                 "The %{attribute} was not accepted; please accept the %{attribute}."
          blank:                    "The provided %{attribute} is blank; please enter a non-blank %{attribute}."
          confirmation:             "The provided %{attribute} does not match the corresponding entry; please re-check this entry against the original."
          empty:                    "The provided %{attribute} is empty; please enter a non-empty %{attribute}."
          equal_to:                 "The provided %{attribute} is incorrect; please enter exactly %{count}."
          even:                     "The provided %{attribute} is odd; please enter an even %{attribute}."
          exclusion:                "The provided %{attribute} is reserved; please enter a different %{attribute}."
          greater_than:             "The provided %{attribute} is too small; please provide a different %{attribute} greater than %{count}."
          greater_than_or_equal_to: "The provided %{attribute} is too small; please provide a different %{attribute} greater than or equal to %{count}."
          inclusion:                "The chosen %{attribute} is not available; please choose an available option." # Rails 4 and prior.
          inclusion_of:             "The chosen %{attribute} is not available; please choose an available option." # Rails 5 and later.
          invalid:                  "The provided %{attribute} is invalid; please enter a valid %{attribute}."
          in_between:               "The provided %{attribute} is outside of the accepted range; please enter a different %{attribute} within the range of %{min} to %{max}."
          less_than:                "The provided %{attribute} is too large; please provide a different %{attribute} less than %{count}."
          less_than_or_equal_to:    "The provided %{attribute} is too large; please provide a different %{attribute} less than or equal to %{count}."
          not_a_number:             "The provided %{attribute} is not numeric; please enter a numeric %{attribute}."
          odd:                      "The provided %{attribute} is even; please enter an odd %{attribute}."
          record_invalid:           "The %{attribute} is invalid. %{errors}"
          spoofed_media_type:       "The provided %{attribute} is invalid (often due to an incorrect file extension); please provide a valid %{attribute}, including an appropriate file extension."
          too_long:                 "The provided %{attribute} contains more than the %{count} available characters; please shorten the entry."
          too_short:                "The provided %{attribute} contains fewer than the %{count} required characters; please lengthen the entry."
          taken:                    "The provided %{attribute} is already taken; please enter a different %{attribute}."
          wrong_length:             "The provided %{attribute} contains the wrong amount of characters; please adjust the entry to exactly %{count} characters."
    

    【讨论】:

    • 谢谢,但我刚刚尝试过,仍然遇到同样的问题。我相信您对格式的看法是正确的,并且它正在获取正确的翻译。它只是没有在error.message 中返回
    • @xxcellerator 感谢您的意见。请参阅上面的编辑。
    • 感谢您的信息。我从来没有意识到救援有这种行为。有没有办法拯救(或更好地处理错误),以便我可以获得该验证消息?
    • 如果您多解释一下您要完成的工作,可能会有所帮助。需要做你要求做的事情是非常罕见的。但是,如果您能多解释一下您的流程,我可能会提供帮助。例如,是什么引发了您要从中营救的 StandardError?当您应该使用#save 时,您是否可能使用#save!?无论哪种方式,更多细节都会有所帮助。
    • 我只是想捕捉错误并将验证消息返回给调用 api 的用户。引发的错误是ActiveRecord::RecordInvalid。我更新了救援块以查看该错误类,但它仍然无法正常工作。无论我使用save! 还是update!,我都会遇到同样的问题。我尝试切换到save 和valid? 检查和引发错误的方法。但是,在这两种情况下,当我通过item.errors.messages 挖掘错误时,我得到{:cost=>["must be greater than or equal to 0"]},但如果我这样做item.errors.full_messages,我得到[]。
    【解决方案2】:

    经过一番挖掘,我发现它与自定义错误消息无关,而是缺少 errors.full_messages 始终为空,这会影响每种类型的验证错误(可能还有其他类型的错误)。

    一旦我深入研究了该方法,我发现它被 gem dynamic_form 覆盖。我能够删除宝石并解决了问题。我现在看到所有错误消息都正确返回了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-07-07
      • 1970-01-01
      • 1970-01-01
      • 2020-06-20
      • 1970-01-01
      • 2016-11-08
      • 2022-01-26
      • 2018-06-15
      相关资源
      最近更新 更多