自定义错误消息处理器没有猴子补丁

时间:2012-11-12 03:33:08

标签: ruby-on-rails-3 internationalization rubygems

我为韩语实现了自定义错误消息处理器。在韩语中,后置词根据前面的名词或代词的声音采取不同的形式。

例如,在标记主题时,在元音后使用 ka(가),在辅音后使用 i(이)

示例(连字符用于表示语素边界):

Romanization: sakwa-ka ppalkah-ta.
Gloss:        Apple-SUBJECT red-PRESENT.
Translation:  Apple is red.

Romanization: phainayphul-i tal-ta.
Gloss:        Pineapple-SUBJECT sweet-PRESENT.
Translation:  Pineapple is sweet.

因此,在ActiveModel :: Errors中实现的标准错误消息系统不适合韩语。你应该在消息中包含属性,制作大量重复项(“A为空白”,“B为空白”,“C为空白”,......),或者避免在属性之后的后置位置,这通常很难或使得尴尬的句子。

我修补了ActiveModel :: Errors并修改了generate_message来解决这个问题。以下是我的Rails应用程序中当前位于config/initializers的代码(Gist)。

# encoding: UTF-8
# Original article: http://dailyupgrade.me/post/6806676778/rubyonrails-full-messages-for-korean
# Modified to support more postpositions and client_side_validations gem.
#
# Add Korean translations like this:
#   ko:
#     errors:
#       format: "%{message}"
#       messages:
#         blank: "%{attribute}((이)) 입력되지 않았습니다"
#         taken: "이미 사용 중인 %{attribute}입니다"
#         invalid: "잘못된 %{attribute}입니다"
#         too_short: "%{attribute}((이)) 너무 짧습니다"
#

class Korean

  POSTPOSITIONS = {"은" => "는", "이" => "가", "을" => "를", "과" => "와", "으로" => "로"}

  def self.select_postposition(last_letter, postposition)
    return postposition unless last_letter >= "가" && last_letter <= "힣"
    final = last_letter.mb_chars.last.decompose[2]
    if final.nil?
      # 받침 없음
      POSTPOSITIONS[postposition] || postposition
    elsif final == "ㄹ" && (postposition == "으로" || postposition == "로")
      # 'ㄹ 받침 + (으)로'를 위한 특별 규칙
      "로"
    else
      # 받침 있음
      POSTPOSITIONS.invert[postposition] || postposition
    end
  end
end

module ActiveModel

  class Errors

    old_generate_message = instance_method("generate_message")

    define_method("generate_message") do |attribute, type = :invalid, options = {}|
      msg = old_generate_message.bind(self).(attribute, type, options)
      return msg unless I18n.locale == :ko
      msg.gsub(/(?<=(.{1}))\(\((은|는|이|가|을|를|과|와|으로|로)\)\)/) do
        Korean.select_postposition $1, $2
      end
    end
  end
end

我的第一个问题是,如果没有猴子补丁,是否有可能实现相同的目标。我是Rails(也是Ruby)的新手,所以无法找到更好的解决方案。

第二个问题是从我的Rails应用程序中提取此代码并将其转换为单独的gem。我正在开发宝石,最近制作了my first gem。我应该在什么地方将此代码放在gem中? config/initializers似乎不对。

1 个答案:

答案 0 :(得分:0)

我不擅长红宝石但是下面的javascript代码做同样的事情。我希望它可以提供帮助。

var hasJongsung = function(word) {
  return !!(word && word[word.length -1].charCodeAt()>=0xAC00 && word[word.length-1].charCodeAt()<=0xD7A3 && (word[word.length -1].charCodeAt()-0xAC00)%28);
};

源:http://spectrumdig.blogspot.kr/2012/11/unicode-20.html