日本語化その3

I18n事前調査メモ

    • モデル名を取得する方法は
?> I18n.t :visit, :scope=>[:activerecord,:models] 
=> "訪問先"
>> I18n.t 'activerecord.models.visit'
=> "訪問先"
>> Visit.human_name
=> "訪問先"
>> I18n.t :visit_jp ,:scope=>[:activerecord,:attributes,:visit]
=> "名前(JP)"
>> I18n.t 'activerecord.attributes.visit.visit_jp'
=> "名前(JP)"
>> Visit.human_attribute_name "visit_jp"
=> "名前(JP)"

active_scaffoldのlabel

    • 単純にi18nの値を設定するには
  active_scaffold :visit do |config|
    (略)
    columns[:pref].label = config.model.human_attribute_name "pref_id"
    (略)
  end

と行えばいい。

ただ、amatsuda-i18n_generatorsだと
pref_idとかはtranslation_ja.yml
に作成されない(まぁ、訳せないからだろうけど)

だから入力フォームでpref_idをselectにしている場合とかは以下のように書く必要がある
translation_ja.ymlにpref_idを追加した上で

  columns[:pref].label = config.model.human_attribute_name "pref_id"
  columns[:pref_id].label = config.model.human_attribute_name "pref_id"

カコワルイ・・

というわけで回避策を考えてみる

問題なのはamatsuda-i18n_generatorsを使った場合
Visit.human_attribute_name "pref"
などとした場合
pref_idがいないので日本語がとれない。
ただ、[関連名_id]は、他のModelと関連があるはずなので
human_attribute_nameで名前が取れないときはModel名をとってこれればいいのでは?*1

Visit.human_attribute_name "pref_id"
とした場合は内部的に
Pref.human_nameの結果を返すようにしたい!!
と思った

次の2ファイルを追加

 ~/acwork/config/initializers: less init_lib.rb 
require 'active_record_ext'

 ~/acwork/lib: less active_record_ext.rb
module ActiveRecord
  class Base
    def self.human_attribute_name(attribute_key_name, options = {})
      defaults = self_and_descendents_from_active_record.map do |klass|
        :"#{klass.name.underscore}.#{attribute_key_name}"
      end
      defaults << options[:default] if options[:default]
      defaults.flatten!
      defaults << attribute_key_name.humanize
      options[:count] ||= 1
      t = I18n.translate(defaults.shift, options.merge(:default => defaults, :scope => [:activerecord, :attributes]))
      return t unless defaults.to_s == t
      I18n.translate("#{attribute_key_name.gsub('_id','')}", options.merge(:default => defaults, :scope => [:activerecord, :models]))
    end
  end
end

これで

?> Visit.human_attribute_name "pref_id"
=> ""

と取れるようになった

ここまでやったら、コントローラーで

  active_scaffold :visit do |config|
    (略)
    config.columns.each do |colum|
      colum.label = colum.active_record_class.human_attribute_name colum.name.to_s
    end
    (略)
  end

とやると一発で日本語化できた。*2

*1:規約から外れない限り

*2:外部キー、モデル名などを規約にのっとらない場合は、いいやり方が思いつきませんでした。。