Railsアプリケーションの国際化 - Globalize

投稿者 nanki 2007-08-26 10:15:00 GMT

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とケンカするかと思ったけど、一緒に動いた。 偶然かもしれないけど。

screenshot

そんなこんなで、↑こんなアプリケーションができてしまう。
はたして、使う機会は訪れるのか?

追記:

  • 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
参考:

This entry was posted on 2007-08-26 10:15:00 GMT and カテゴリ , , . You can follow any response to this entry through the Atom feed. or a trackback from your own site.

タグ , ,


トラックバック

トラックバックリンク:
http://blog.netswitch.jp/trackbacks?article_id=8595