Tech Racho エンジニアの「?」を「!」に。
  • 開発

Rails DBから取得した値を国際化するヘルパー

多言語サイトを作っていて、マスタデータも多言語化したい、でもそのためにテーブル増やしたりプラグイン入れるほどのものでもない・・・といったときに、簡単にカラムデータを国際化(i18n)できるヘルパーです。

国際化しよう★


たとえば、「ランク」という機能があって、ユーザはbeginner, intermediate, seniorのどれかに属するようなとき、以下のようなシンプルなテーブルを作り、UserはRankにbelongs_toするとします。
DBには、英語の文字列でも入れておきます。

create_table :ranks do |t|
  t.string :name
end

以下のようなヘルパーを作ってやります。

#lib/acts/column_i18n.rb
#localizableとかのほうが格好いいが、たまたま他で使っていたので、かぶらないように変な名前にした
module Acts::Column18n
  def acts_as_column_i18n(*columns)
    raise ArgumentError, 'columns is required' if columns.empty?

    columns.each do |col|
      define_method "#{col}_i18n" do
        val = __send__ col
        begin
          I18n.t("models.#{self.class.model_name.underscore}.#{col}.#{val}", :raise => true)
        rescue
          val
        end
      end
    end
  end
end

あとは読み込ませれば、

#app/models/application_model.rb
class ApplicationModel < ActiveRecord::Base
  extend Acts::ColumnI18n
end
#app/models/rank.rb
class Rank < ApplicationModel
  acts_as_column_i18n :name
end

以下のように、カラム名_i18n でアクセスできます。

<!--app/views/users/show.html.erb-->
<h1>User</h1>
Name: <%= @user.rank.name_i18n >

言語ファイルを書かない場合、DBに入っている生の値がそのまま返ります。
YAMLをちゃんと書くと、対応したものが取得できます。

#config/locales/ja.yml
ja:
  models:
    rank:
      name:
        beginner: "初級"
        intermediate: "中級"
        senior: "上級"

追加するたびにYAMLの更新が必要になるので、DB化するメリットをつぶしているといればそれまでですが、
国際化は、途中で挫折しないためにめんどくさくないことが重要です。別にYAML書かなくても英語になるだけ、DB変更は一切不要のこの手法は気に入っています。

CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。