Railsアプリケーションの国際化 - Globalize
Globalizeを使ってみる。
セットアップ
適当なRailsアプリを作って、Globalizeをインストール。
$ script/plugin install http://svn.globalize-rails.org/svn/globalize/trunk .... $ mv vendor/plugins/trunk vendor/plugins/globalize $ rake globalize:setup
CSV::Cellがinspectされたようなエラーが出るので、vendor/plugins/globalize/tasks/data.rake を修正する。
--- ./vendor/plugins/globalize/tasks/data.rake.orig 0000-00-00 00:00:00.000000000 +0000
+++ ./vendor/plugins/globalize/tasks/data.rake 0000-00-00 00:00:00.000000000 +0000
@@ -17,3 +17,3 @@
- columns = reader.shift.map { |column_name| cnx.quote_column_name(column_name) }
+ columns = reader.shift.map { |column_name| cnx.quote_column_name(column_name.data) }
column_clause = columns.join(', ')
@@ -24,3 +24,3 @@
raise "No header defined" unless column_clause
- values_clause = row.map { |v| cnx.quote(v).gsub('\\n', "\n").gsub('\\r', "\r") }.join(', ')
+ values_clause = row.map { |v| cnx.quote(v.data).gsub('\\n', "\n").gsub('\\r', "\r") }.join(', ')
sql = "INSERT INTO #{table_name} (#{column_clause}) VALUES (#{values_clause})"さらに、vendor/plugins/globalize/data/language_data.csv の空行がエラーを起こしているので修正。
$ rake globalize:setup ...
成功。
View翻訳
base_languageを英語に。
# config/environment.rb
Globalize::Locale.set_base_language("en-US")$ script/console
>> "March [month]".t
=> "March"
>> Globalize::Locale.set("ja-JP")
=> #<Globalize::Locale...
>> "March [month]".t
=> "3月"
>> Time.now.loc "%A"
=> "日曜日"ふむふむ。この辺は、gettextの方が使いやすそうかなぁ。
Model翻訳
適当なモデルを作成
$ script/generate model Product ...
# db/migrate/001_create_products.rb
def self.up
create_table :products do |t|
t.column :name, :string
t.column :manufacturer, :string
end
end$ rake db:migrate
$ script/console
>> p = Product.create :name => "Pucchin Pudding", :manufacturer => "Glico"
=> #<Product:...
>> p.name
=> "Pucchin Pudding"
>> p.manufacturer
=> "Glico"
# jaで保存。
>> Globalize::Locale.set("ja-JP")
>> p.name = "プッチンプリン"
>> p.manufacturer = "グリコ"
>> p.save
=> true
# jaで読む。
>> p.reload
>> p.name
=> "プッチンプリン"
>> p.manufacturer
=> "グリコ"
# enで読む。
>> Globalize::Locale.set("en-US")
>> p.reload
>> p.name
=> "Pucchin Pudding"
>> p.manufacturer
=> "Glico"ちゃんと動いてる。
この時、productsテーブルにはbase_languageで格納され、それとは別にglobalize_translationsテーブルに、翻訳情報を保持している。
sqlite> SELECT * FROM globalize_translations WHERE id > 7088; id type tr_key table_name item_id facet built_in language_id pluralization_index text namespace ---------- ---------------- ---------- ---------- ---------- ---------- ---------- ----------- ------------------- --------------------- ---------- 7089 ModelTranslation products 18 name t 2723 プッチンプリン 7090 ModelTranslation products 18 manufactur t 2723 グリコ
Object#_が定義されていたので、gettextとケンカするかと思ったけど、一緒に動いた。 偶然かもしれないけど。

そんなこんなで、↑こんなアプリケーションができてしまう。
はたして、使う機会は訪れるのか?
追記:
- eager loadingを行う時は、:include_translatedを使う。
- が、対応が中途半端で、user.product_nameとアクセスしないとだめっぽい。
class User
belongs_to :product
end
user = User.find(:first, :include_translated => :product)
user.product.name #=> NG
user.product_name #=> OK