ActiveModel :: Errors中的编码问题

时间:2016-04-17 22:24:08

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-4 character-encoding cjk

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库,我不知道它是否可能。

请给我一些提示。感谢。

1 个答案:

答案 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"