読む]で取り上げました。デフォルト設定ではRailsは国際化の情報をYAMLファイルに保存しますが、今回のエピソードでは別のバックエンドの使い方を紹介します。下の図は簡単なRailsサイトのページです。このページのヘッダーテキストを国際化してみましょう。translateメソッド(短縮形はt)を使えばRailsアプリケーションのテキストの一部を簡単に国際化できます。その場合、アプリケーションがサポートする言語ごとにYAMLファイルを編集して、キーとその言語のテキストを追加する必要があります。大規模なアプリケーションの場合、この方法はすぐに退屈な作業になってしまいます。そもそも国際化テキストを書くのは本来は開発者の仕事ではありません。アプリケーションの管理者が国際化テキストの追加や編集ができるウェブ画面を提供できれば、ずっと便利になるでしょう。gemは複数のバックエンドをサポートしています。YAMLだけに縛られることなく、気に入ったデータベースバックエンドを選んで使うことができます。backendを使用して、YAMLファイルで翻訳文を管理します。backendというバックエンドで、翻訳文を関するためにどのようなkey-valueストアでも使用することができます。ActiveRecordに保存する機能を抽出した別のgemもあります。これも動くことは動くのですが、アプリケーションの各ページ上の翻訳文に頻繁にアクセスされるため、ActiveRecordというのはベストな方法とは言えないでしょう。翻訳文は、SQLデータベースではなくできればメモリ上に保持したいところです。この問題を解決するためにキャッシュ機能を利用できるかも知れませんが、翻訳文が修正された場合にはキャッシュを使用させないなどの制御に気を配らなくてはいけないのが煩雑です。これらの理由からkey-valueストアを選択することとし、今回のエピソードで紹介していきます。バックエンドを変更するまずヘッダの静的テキストを修正し、代わりに翻訳を使用するようにします。welcomeというキーに対応づけます。%></h1>そして、英語用のYAMLファイルに翻訳テキストを追加します。"Welcome"ここでページを再度読み込むと、YAMLファイルのテキストが表示されているのがわかります。デフォルトのバックエンドを使った翻訳テキストがあるので、バックエンドを変えてみることにしましょう。key_value.rbファイルの最初のコメント部分に、使い方の説明と別のバックエンドを設定する方法が記述されています。I18n::Backend::KeyValue.new(Rufus::Tokyo::Cabinet.new('*'))I18n::Backend::KeyValueを新規に作成し、使用したいkey-valueストアを指定します。それが翻訳テキスト管理のバックエンドとして使用されます。このバックエンドのデータベースは、3つのメソッドに応答できる必要があります。キーの値を取得する、値を設定する、すべてのキーのリストを得る、の3つです。この情報はコメント欄に記述されています。Rubyのほとんどのkey-valueストアはこれらのメソッドをサポートしているので、そのまま使うことができます。keysこれでアプリケーションの国際化用のバックエンドを入れ替える準備が整ったので、作業を始めることにしましょう。/config/initializersディレクトリ内にi18n_backend.rbというファイルを新規作成します。Cabinetを使用していますが、今回のアプリケーションをとりあえず動かすために空のハッシュを使用します。実際のアプリケーションではこのようなことはしませんが、これは先ほどの3つのメソッドをサポートする一番単純なもので、デモ目的には十分です。ここでアプリケーションを再起動してトップページに行くと、タイトルが正しく表示されていません。ソースコードを見ると、「翻訳がみつからない」とあります。welcome</span></h1>アプリケーションが新しいバックエンドを使用しているので、翻訳がないと表示されています。YAMLファイルには残っているのですが、新しいバックエンドにはまだ翻訳がないからです。そこでウェブ画面を新たに作成して、ユーザが新しいバックエンドに翻訳文を追加できるようにします。これを、新しいTranslationsControllerのindexアクションで処理します。"translations/index")を、resourcesの呼び出しに書き換えます。"home#index"endindexアクションで、翻訳が存在する場合はそれを表示するために、新しいバックエンドからハッシュ形式の翻訳テキストを取得します。そのためにI18n.backend.storeを呼び出します。endendビュー内で翻訳を順番に取得して表示していきます。%></ul>このコードがハッシュ内のすべての翻訳をループして、すべてのキーと値をリスト表示します。新しい翻訳を追加する手段が必要なので、リストの下にフォームを作ります。%>このフォームは、TranslationControllerのcreateアクションにPOSTします。フォームには次の3つのフィールドがあります。言語のロケール(例えば、英語の場合はen)、キー(ビューファイル内の翻訳対象を特定します)、そして翻訳されたテキストです。createアクションで、I18n.backend.store_translationsを呼び出して、フォームに入力された値に基づいて新しい翻訳文を追加します。その時に3つの引数を指定します。1つ目はロケールで、フォームから取得します。2つ目はハッシュ形式のデータで、内容は自由です。フォーム上のフィールドから、キーと値を渡します。最後の引数escapeは、キーにおいてピリオドをエスケープするかどうかを決定します。ピリオドは、キーの区切りとして使うので、ここではfalseに設定します。translations"end新しく作ったフォームの動作を確認するために、トップページの翻訳がない部分を追加してみましょう。トップページに戻ってみると、翻訳されたヘッダ文が新しく設定したバックエンドから取得され表示されています。バックエンドにRedisを使用する新しいバックエンドはうまく動くようになりましたが、値をRubyのハッシュに保存しているため、Webサーバを再起動したらすべて無くなってしまいます。翻訳文の保存のためには、より永続的な保存場所が必要です。そこでこのアプリケーションのために、永続的なkey-valueストアであるRedisを使用することにします。Macを使用しているのであれば、Redisをインストールする一番簡単な方法はHomeBrewです。インストールは、次のコマンドを実行します。redisインストールができたら、指示に従ってRedisサーバを起動します。通常は、簡単にredis-serverを実行するだけです。gemをインストールします。そのためにGemfileにgemへの参照情報を追加し、bundleコマンドを実行します。'redis'これで、バックエンドの設定でハッシュを指定している部分を、Redisデータベースに置き換えられます。(本番)のそれぞれのモードで違うデータベースを指定することもできます。バックエンドをkey-valueストアに変更したのに合わせて、翻訳画面のコードも変更します。現状ではハッシュ内をループしているものを、Redisデータベース内をループさせるよう、コードの以下の部分を変更します。%></ul>これを次のように変更します。%></ul>これで@translationsはRedisデータベースのインスタンスを参照するようになりました。eachには対応しないので、keys内で繰り返し処理をおこなうように変更します。この部分では、キーとそれに対応する値を表示します。これで翻訳文のための永続的な保存場所ができたので、アプリケーションのサーバを再起動してもフォームから追加した翻訳が失われることはありません。そこでここからは、Key-valueストアから値を取得できない部分について代替のYAMLファイルを使用する方法を説明します。前に作成した初期設定ファイルでバックエンドを定義した部分を修正します。KeyValueバックエンドを直接使用するのではなく、代わりにChainバックエンドを使用します。Chainバックエンドから複数のバックエンドが順番に呼び出され、与えられた翻訳キーに対応する値が見つかればそれが返されます。I18n.backend)最初にRedisバックエンドを、次にデフォルトバックエンドを指定しています。アプリケーションはRedisデータベースで翻訳文を探し、対応するキーを見つけられなかった場合、YAMLファイルを参照します。この方法でバックエンドを設定すると、key-valueストアに直接アクセスするのが困難になります。この問題を回避するために、データベースを定数で指定して外に出します。I18n.backend)これによって、アプリケーション内でkey-valueストアにアクセスする必要がある場合、例えばTranslationsController内で、この定数を使うことができます。I18n.backend.storeを呼び出すことはできません。TRANSLATION_STOREendRedisデータベースから保存された翻訳文を削除してトップページにアクセスしてみると、YAMLファイルからの翻訳文が表示されているのがわかります。翻訳文を元に戻すとそちらが優先され、Redisデータベースからの値が表示されます。今回のエピソードはこれで終わりです。これで、ウェブ画面から翻訳文を編集できるシステムができたので、YAMLファイルを直接編集しなくてもよくなりました。実稼働中のアプリケーションでこのようなことを行う場合、使い勝手をよくするにはいろいろと作り込める部分はありますが、基本的な部分は今回紹介したとおりです。Applications”をお勧めします。現在ベータ版が入手可能で、今回のエピソードを執筆するのに非常に参考になりました。