我已经为韩语实现了一个自定义错误消息处理器。在韩语中,根据前面的名词或代词的发音,后置词采用不同的形式。
例如,在标记主语时,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 应用程序中的代码 ( Gist )。config/initializers
# 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。我正在努力开发宝石,最近制作了我的第一颗宝石。我应该把这段代码放在 gem 的什么地方?config/initializers
似乎不对。