J'ai implémenté un processeur de message d'erreur personnalisé pour le coréen. En coréen, les postpositions prennent différentes formes en fonction du son du nom ou du pronom précédent.Processeur de message d'erreur personnalisé sans patch singe
Par exemple, lors du marquage d'un sujet, ka (가) est utilisé suivant une voyelle et i (이) est utilisé suivant une consonne.
Exemples (traits d'union sont pour indiquer les limites morphème):
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.
Par conséquent, le système standard de message d'erreur mis en œuvre dans les erreurs de ActiveModel ne suffit pas pour le coréen. Vous devriez soit inclure l'attribut dans le message en faisant beaucoup de doublons ("A est vide", "B est vide", "C est vide", ...), ou éviter les postpositions après l'attribut qui est souvent difficile ou fait phrases maladroites.
Je singe patché ActiveModel :: Erreurs et modifié generate_message
pour résoudre ce problème. Voici le code (Gist) qui est actuellement dans config/initializers
dans mon application Rails.
# 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
Ma première question est de savoir s'il est possible d'atteindre le même objectif sans patch de singe. Je suis nouveau à Rails (et Ruby aussi) donc je n'ai pas pu trouver une meilleure solution.
La deuxième question consiste à extraire ce code de mon application Rails et à en faire un joyau distinct. Je suis en train de me couper les dents en développant des gemmes et j'ai récemment fabriqué my first gem. A quel endroit dois-je mettre ce code dans un bijou? config/initializers
ne semble pas juste.