I18n从utf-8格式的yml读取,而translate将从utf-8转换为utf-8。
我的遗留代码严重依赖于ActiveModel :: Errors.full_messages,
,例如,
# note: the message is not utf-8 encoding
validates_length_of :title,:maximum => 2,:message => 'abc'.encode("shift_jis")
在视图中,它使用:
item.errors.full_messages.each do |msg|
end
错误将类似于:
I18n.t(:title) + " " + 'abc'
事实上,在full_message函数中,真正的源代码如下:
def full_message(attribute, message)
return message if attribute == :base
attr_name = attribute.to_s.tr('.', '_').humanize
attr_name = @base.class.human_attribute_name(attribute, default: attr_name)
I18n.t(:"errors.format", {
default: "%{attribute} %{message}",
attribute: attr_name,
message: message
})
end
现在的问题是:%{attribute}是utf-8,%{message}不是utf-8,因此调用full_message时会出错。
我能想到几种解决方案:
1)将错误消息更改为utf-8(还有很多其他字符串是非utf-8),因此我必须处理utf-8和非utf-8的组合。源代码,当它们聚集在一起时进行适当的转换。
2)找到一种枚举错误消息的方法(类似于full_messages),但使用不同的实现。我试图查看ActiveModel :: errors的API,但找不到内部API,以便我可以枚举错误。
3)改变I18n.t默认行为,使其返回非utf-8。
4)更改ActiveModel :: Errors.full_messages,使其返回非utf-8。
第二个选项实际上是最好的选项,但我不确定如何以与full_messages相同的方式枚举错误消息。我找不到任何公共API来返回错误的内部数据结构?
最后两个选项需要注入ruby库,我不知道它是否可能。
请给我一些提示。感谢。
答案 0 :(得分:1)
你可以改变ruby(和rails)中几乎所有东西的行为。
只需在config / initializers中创建一个新的初始化文件,如下所示:
#monkeypatch_i18n.rb
(i don't know the exact path of active_model/errors.full_messages)
module ActiveModel
module Errors
def full_messages
#new logic
end
end
end
这会覆盖默认方法。
的问候, 胡安马。
编辑: 更清洁的解决方案可能是:
#lib/monkey_patch_i18n.rb
module ActiveModel
module Errors
def full_messages
#new logic
end
end
end
#config/initializers/init_i18n.rb
require "#{Rails.root}/lib/monkey_patch_i18n.rb"