gettextでSTIのカラム名もローカライズさせる
gettextはすごく便利なのですが、STIを使うと不具合があることがわかりました。
上のようなUser < Manager < Administrator
のような継承関係にあるモデルを用意します。
そして、
rake updatepo
して、sample.poを作成します。
中を見ると、
#: app/models/user.rb:-
msgid "User|Email" msgstr "メールアドレス"
こんな感じにして、いつものように
rake makemo
してmoファイルを作成します。
そして、userモデルのerror_messages_forを見てみます。
すると、@userがUserクラスの場合は問題なく表示されるのですが、
@userがManagerクラスやAdministratorクラスの場合はカラム名は知らんぷりです。
STIを使って継承してモデルを作成すると、カラム名についてはそこまでgettextで
考慮してくれないようです。
そのため、パッチを作成してみました。
このパッチを当てるとUser:Emailにロケールが無い時は、
Manager:Email、Administrator:Emailを探してくれます。
--- /opt/local/lib/ruby/gems/1.8/gems/gettext-1.10.0/lib/gettext/active_record.rb 2007-09-27 16:39:55.000000000 +0900 +++ vendor/plugins/gettext-1.10.0/lib/gettext/active_record.rb 2007-09-27 17:07:29.000000000 +0900 @@ -255,7 +255,7 @@ if attr == "base" full_message = custom_msg elsif /%\{fn\}/ =~ custom_msg - full_message = custom_msg % {:fn => @base.class.human_attribute_name(attr)} + full_message = custom_msg % {:fn => sti_fn_of(attr)} elsif append_field full_message = @base.class.human_attribute_name(attr) + " " + custom_msg else @@ -264,6 +264,20 @@ full_message end + private + def sti_fn_of(attr) + klass=@base.class + while(klass!=klass.base_class) + fn=klass.human_attribute_name(attr) + if fn==attr + return fn + end + klass=klass.superclass + end + return @base.class.human_attribute_name(attr) + end + + public def localize_error_messages(append_field = true) # :nodoc: # e.g.) foo field: "%{fn} foo" => "Foo foo", "foo" => "Foo foo". errors = {}
3日経って、武藤さんがこのブログに気づかなかったらメールしよう。