多言語サイトを作っていて、マスタデータも多言語化したい、でもそのためにテーブル増やしたりプラグイン入れるほどのものでもない・・・といったときに、簡単にカラムデータを国際化(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変更は一切不要のこの手法は気に入っています。