【问题标题】:Filtering Rails validation errors with multiple languages (I18n)使用多种语言过滤 Rails 验证错误 (I18n)
【发布时间】:2019-03-12 10:57:46
【问题描述】:

我想拦截 Rails 在注册表单上抛出的验证错误。在英语中,它是这样工作的:

if @user.save

  # Do whatever...

else

  @errors = @user.errors.full_messages

  if !@errors.index("Email has already been taken").nil?

    # Present the user with a 'forgot password' UI

  else

    # Display the error on the screen

  end

end

由于特定错误的测试是基于硬编码的字符串比较,所以它有点脆弱,但当我只有少数异常情况时它可以工作。

但是,当使用一种以上的语言时,这变得非常笨拙,因为验证错误已经被本地化了,我不得不使用像这样的可怕的东西:

if !@errors.index("Email has already been taken").nil? ||
   !@errors.index("Email n'est pas disponible").nil? ||
   !@errors.index("Email wurde bereits angenommen").nil? || ...

我想 Rails 可以给我一个状态码(就像 HTTP 一样),所以我不需要比较字符串,但我还没有看到任何地方的记录。

最好的解决方法是什么?

【问题讨论】:

标签: ruby-on-rails internationalization rails-i18n


【解决方案1】:

您应该能够通过询问@user.errors.details 获得更多详细信息。它在guide to validations 中得到了简短的提及。

基本上,当您收到电子邮件时,您应该会看到类似这样的内容:

> user.errors.details
=> { :email => [{:error => :taken, :value => 'exists@example.org'}] }

这将允许您检查“已接受”电子邮件:

if @errors.details[:email] &&  
  @errors.details[:email].any? { |error| error[:error] == :taken }

【讨论】:

  • 理想情况下,您可以将其移动到模型中的方法中。
  • 是的,“采取”检查可以根据需要在控制器或模型中。
  • def email_taken?; errors.details[:email].any? { |error| error[:error] == :taken }; end.
  • 太棒了。感谢 Shadwell 和 @max。
猜你喜欢
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多