Ruby on Rails i18n - 想要翻译模型中的自定义消息

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17935597/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 22:26:07  来源:igfitidea点击:

Ruby on Rails i18n - Want To Translate Custom Messages in Models

ruby-on-railserror-handlinglocalizationinternationalizationmessage

提问by Pamela Cook - LightBe Corp

I have attributes with special validation where I use the message clause to display a special message just for that validation. Here is one example:

我有带有特殊验证的属性,我使用 message 子句来显示仅用于该验证的特殊消息。这是一个例子:

validates :email, presence:   true, length: { maximum: 60 },
                format:     { with: valid_email_regex, message: "is not a valid email address format." },
                uniqueness: { case_sensitive: false } 

I would like to translate the message here but I am not sure how to do it.

我想在这里翻译这条消息,但我不知道该怎么做。

I have seen examples where they type something like this: message: t("some_value_here"). I'm not sure about the designation. I tried something like this message: t(:bad_email). I did the following in my yaml file just to try something.

我见过他们输入这样的例子:message: t("some_value_here")。我不确定这个名称。我尝试过类似这样的消息:t(:bad_email)。我在我的 yaml 文件中做了以下操作只是为了尝试一些东西。

activemodel:
  errors:
    bad_email: "is not a valid email address format."

When I tried to access my Rails application I got the following error:

当我尝试访问 Rails 应用程序时,出现以下错误:

ActionView::Template::Error (undefined method `t' for #<Class:0x007fefc1b709e0>)

I also tried this in my yaml file:

我也在我的 yaml 文件中尝试过这个:

activemodel:
  errors:
    user:
      bad_email: "is not a valid email address format."

I have been researching this off and on all day long. All I can find is to replace built-in error hashes like blank or empty. Is there a way for me to have custom error hashes and replace them in the model? At this point I cannot get the t to work as coded. My hope is that the problem is how I have my yaml file set up. I have seen varying versions of how to set this up. I am not sure if I should put this under activemodel or activerecord. I assumed activemodel since that is where the custom message is that I want to translate.

我整天都在断断续续地研究这个。我能找到的只是替换内置的错误哈希,如空白或空。有没有办法让我拥有自定义错误哈希并在模型中替换它们?在这一点上,我无法让 t 按照编码工作。我希望问题在于我如何设置 yaml 文件。我已经看到了如何设置它的不同版本。我不确定是否应该将它放在 activemodel 或 activerecord 下。我假设了 activemodel,因为这是我想要翻译的自定义消息。

Any help would be appreciated. This is the last piece I need to figure out before launching my first translation of the application.

任何帮助,将不胜感激。这是我在启动我的应用程序的第一次翻译之前需要弄清楚的最后一部分。

UPDATE 7/29/2013 7:30 pm CDT

更新 7/29/2013 7:30 pm CDT

bgatesgave me a very good start with how to setup my model files to receive the custom message in the YAML file. However I ended up having to do the following setup in my yaml file for the custom messages to be found.

bgates在如何设置模型文件以接收 YAML 文件中的自定义消息方面给了我一个很好的开端。但是,我最终不得不在我的 yaml 文件中进行以下设置才能找到自定义消息。

activerecord:
  errors: 
    models: 
      user: 
        attributes: 
          bio: 
            no_links: "cannot contain email addresses or website links (URLs)."
          email: 
            bad_email: "is not a valid email address format."
          username: 
            bad_username: "can only contain numbers and letters.  No special characters or spaces."

回答by bgates

Use a symbol for the message:

为消息使用符号:

validates :email, presence:   true, length: { maximum: 60 },
            format:     { with: valid_email_regex, message: :bad_email },
            uniqueness: { case_sensitive: false } 

then in the yaml file

然后在yaml文件中

[lang]:
  activerecord:
    errors:
      messages:
        bad_email: "just ain't right"

If there's a translation specific to this model, it will override the general one above:

如果有特定于此模型的翻译,它将覆盖上面的一般翻译:

[lang]:
  activerecord:
    errors:
      models:
        model_name: # or namespace/model_name
          attributes:
            email:
              bad_email: "model-specific message for invalid email"

If you write custom validations, add_error(:email, :bad_email)will do the lookup above, but errors[:email] << :bad_emailwill not.

如果您编写自定义验证,add_error(:email, :bad_email)将执行上面的查找,但errors[:email] << :bad_email不会。

回答by oma

I just walked through all this and found the rails guides for custom validatorstoo hard-coded... I'm posting this here even though it's not exactly what you asked, but the Q title fits perfectly (which is why I read this post for my problem).

我刚刚完成了所有这些,发现自定义验证器导轨指南太硬编码了......我在这里发布了这个,即使它不是你问的那样,但 Q 标题非常适合(这就是我阅读这篇文章的原因)对于我的问题)。

Custom validation with i18n message:

使用 i18n 消息进行自定义验证:

validate :something_custom?, if: :some_trigger_condition

def something_custom?
  if some_error_condition
    errors.add(:some_field_key, :some_custom_msg)
  end
end

# en.yml
activerecord: 
  errors:
    models:
      some_model:
        some_custom_msg: "This is i18n controlled. yay!"

回答by BookOfGreg

The solution to this does not need to be custom; The formatvalidator message already maps to the :invalidsymbol. You need only set the invalid in translation.

对此的解决方案不需要定制;该format验证消息已经映射到:invalid符号。您只需要在翻译中设置无效。

en:
  activerecord:
    errors:
      models:
        some_model:
          attributes:
            email:
              invalid: "FOO"

Reference: http://edgeguides.rubyonrails.org/i18n.html#error-message-interpolation

参考:http: //edgeguides.rubyonrails.org/i18n.html#error-message-interpolation

回答by Ruto Collins

I will give a complete example.

我会给出一个完整的例子。

To make your models cleaner, you cancreate a custom validation helper method in an entirely new directory - app/validations, which will be autoloaded by Rails.

为了使您的模型更简洁,您可以在一个全新的目录 - 中创建一个自定义验证辅助方法,该目录app/validations将由 Rails 自动加载。

I'll call my file time_validator.rb, located at app/validations/time_validator.rb

我会打电话给我的文件time_validator.rb,位于app/validations/time_validator.rb

My file has the following code, which validates user-entered time - that it is actuallytime.

我的文件有以下代码,它验证用户输入的时间 - 它实际上是时间。

# frozen_string_literal: true

class TimeValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    Time.parse(value).strftime('%H:%M')
  rescue ArgumentError 
    record.errors.add(attribute, :invalid_time)
  end
end

You can read more about creating custom ActiveRecord validations here

您可以在此处阅读有关创建自定义 ActiveRecord 验证的更多信息

Our main point of concern is the record.errorsline. Note that it's attributeand not :attribute, where attributeis the column in your model.

我们主要关注的是record.errors线路。请注意,它是attribute而不是:attributeattribute您的模型中的列在哪里。

:invalid_timeis the key that retrieves your translated content from your locales file. In my case, this is the enfile:

:invalid_time是从语言环境文件中检索翻译内容的键。就我而言,这是en文件:

en
  activerecord:
    errors:
      models:
        home:
          attributes:
            check_in_time:
              invalid_time: Please enter valid time
            check_out_time:
              invalid_time: Please enter valid time

Then in the homemodel:

然后在home模型中:

validates :check_in_time, time: { allow_blank: true }
validates :check_out_time, time: { allow_blank: true }

timeautomatically gets mapped to the class TimeValidator, and the methods therein get run.

time自动映射到类TimeValidator,并运行其中的方法。

Incase this is violated, ActiveRecord will throw an error right below the column name.

如果违反了这一点,ActiveRecord 将在列名正下方抛出错误。

Hope this helps!

希望这可以帮助!