我有使用特殊验证的属性,其中我使用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 }
我想在这里翻译消息,但我不知道该怎么做。
我见过他们输入类似内容的例子:message:t(“some_value_here”)。我不确定这个名称。我试过这样的消息:t(:bad_email)。我在yaml文件中做了以下操作,只是为了尝试一下。
activemodel:
errors:
bad_email: "is not a valid email address format."
当我尝试访问我的Rails应用程序时,出现以下错误:
ActionView::Template::Error (undefined method `t' for #<Class:0x007fefc1b709e0>)
我也在我的yaml文件中尝试了这个:
activemodel:
errors:
user:
bad_email: "is not a valid email address format."
我一整天都在研究这个问题。我能找到的就是替换内置的错误哈希,如空白或空。有没有办法让我有自定义错误哈希并在模型中替换它们?在这一点上,我不能让t以编码方式工作。我希望问题是我如何设置我的yaml文件。我已经看到了如何设置它的不同版本。我不确定是否应将其置于activemodel或activerecord下。我假设有activemodel,因为那是我要翻译的自定义消息。
任何帮助将不胜感激。这是我在启动应用程序的第一次翻译之前需要弄清楚的最后一部分。
更新日期7/29/2013 7:30 pm CDT
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."
答案 0 :(得分:68)
使用符号作为消息:
validates :email, presence: true, length: { maximum: 60 },
format: { with: valid_email_regex, message: :bad_email },
uniqueness: { case_sensitive: false }
然后在yaml文件中
[lang]:
activerecord:
errors:
messages:
bad_email: "just ain't right"
如果有特定于此模型的翻译,它将覆盖上面的一般翻译:
[lang]:
activerecord:
errors:
models:
model_name: # or namespace/model_name
attributes:
email:
bad_email: "model-specific message for invalid email"
如果您编写自定义验证,add_error(:email, :bad_email)
将执行上述查询,但errors[:email] << :bad_email
不会。
答案 1 :(得分:21)
我刚刚完成了所有这些并发现rails guides for custom validators太难编码了...我在这里发布这个,即使它不是你问的那个,但Q标题非常合适(这就是为什么我阅读这篇文章以解决我的问题。)
使用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!"
答案 2 :(得分:2)
解决方案不需要定制; format
验证程序消息已映射到:invalid
符号。您只需要在翻译中设置无效。
en:
activerecord:
errors:
models:
some_model:
attributes:
email:
invalid: "FOO"
参考:http://edgeguides.rubyonrails.org/i18n.html#error-message-interpolation
答案 3 :(得分:0)
我将举一个完整的例子。
为了让你的模型更清洁,你可以在一个全新的目录中创建一个自定义验证助手方法 - app/validations
,它将由Rails自动加载。
我将调用位于time_validator.rb
的文件app/validations/time_validator.rb
我的文件包含以下代码,用于验证用户输入的时间 - 实际时间。
# 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
您可以阅读有关创建自定义ActiveRecord验证here
的更多信息我们关注的主要问题是record.errors
行。请注意,它是attribute
而不是:attribute
,其中attribute
是模型中的列。
: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
然后在home
模型中:
validates :check_in_time, time: { allow_blank: true }
validates :check_out_time, time: { allow_blank: true }
time
会自动映射到类TimeValidator
,其中的方法会运行。
如果违反此规定,ActiveRecord将在列名称下方抛出错误。
希望这有帮助!