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変更は一切不要のこの手法は気に入っています。

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

baba

ゆとりプログラマー。 高校時代から趣味でプログラミングを初め、そのままコードを書き続けて現在に至る。慶應義塾大学環境情報学部(SFC)卒業。BPS設立初期に在学中から参加している最古参メンバーの一人。Ruby on Rails、PHP、Androidアプリ、Windows/Macアプリ、超縦書の開発などを気まぐれにやる。軽度の資格マニアで、情報処理技術者試験(16区分17回 + 情報処理安全確保支援士試験)、技術士(情報工学部門)、Ruby Programmer Gold、AWSソリューションアーキテクト(アソシエイト)、日商簿記2級、漢検準1級などを保有。

babaの書いた記事

夏のTechRachoフェア2019

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ