RubyOnRails を使ってみる 【第 5 回】 ActiveHeart

はじめに

流行のフレームワーク Ruby on Rails (以下 Rails) に興味を持っている、使っているみなさまこんにちは。

突然ですが、Rails を使ってみて 「あれ、ここ英語でハードコーディングされてるよ」 「日本の案件ではこんな機能があったら便利なのに」 と思ったことはありませんか。ありますよね。

そんなことを思っていた矢先、Rails 0.14 がリリースされ、plugin 1 という仕組みが導入されたことを知りました。 この plugin を使えば、日本語まわりや日本の案件で利用できる便利な機能を簡単に追加することができそうです。そう考えて私が実際に作ってみた plugin が今回紹介する ActiveHeart です。

ActiveHeart とは

ActiveHeart とは、前述の通り Rails を日本の環境で使いやすくするための plugin です。 具体的には以下の 3 つのライブラリから構成されています。

ActiveRecordMessagesJa - ActiveRecord のヴァリデートメッセージの日本語化
ActiveRecord のヴァリデートメッセージを日本語に置き換えます。英語がハードコーディングされている部分にも対応しています。
TransSid - session を cookie でなく URL で引き回す
日本の携帯には cookie の使えない機種が多くあります。そのような端末でも session を使えるようにします。
Iso2022jpMailer - 日本語メール送信処理
メールを送信する際、文字コードを iso-2022-jp に変更します。

この plugin をインストールすることによって、上記の機能を簡単に使えるようになります。

利用方法

さっそく ActiveHeart を使ってみましょう。 著者の環境は Ruby 1.8.3, Rails 0.14.3 です。

ActiveRecordMessagesJa

ActiveHeart は ActiveRecord のヴァリデートメッセージを日本語化します。

ActiveHeart をインストールする前に、従来の scaffold で吐きだしたひな形のエラーメッセージを確認しておきましょう。

サンプルとして model は

 class Article < ActiveRecord::Base
   validates_length_of :title, :in => 1..50
   validates_length_of :body, :minimum => 10
 end

となっています。 validate1.png

お馴染みのエラー画面ですね。

では ActiveHeart のインストールです。subversion がインストールされていれば

 $ ./script/plugin install http://svn.rails2u.com/public/plugins/trunk/active_heart/

だけでインストールは完了です! とっても簡単ですね。

subversion が使えないときは、こちらから ActiveHeart のソースをダウンロードして、すべてのファイルとディレクトリをそのまま Rails プロジェクトの vendor/plugins/active_heart/ に置いてください。

./script/server など Web サーバを立ち上げている場合は再起動してください。

では、もう一度エラーメッセージの画面を見てみましょう。 validate2.png

おお、日本語化されていますね!

でもカラム名 Title, Body がそのままエラーメッセージとして表示されてしまっています。これを日本語化するために、model にカラム名に対応する日本語を定義してみましょう。

 class Article < ActiveRecord::Base
   set_field_names :title => 'タイトル', :body => '本文'
   validates_length_of :title, :in => 1..50
   validates_length_of :body, :minimum => 10
 end

set_field_names メソッドを使い、引数のハッシュに対応する名前を入れて設定します。 ではまたまたエラーメッセージの画面を見てみましょう。 validate3.png

今度はばっちりですね!

文字コードについて

ActiveHeart 内部の文字コードは UTF-8 になっています。 それ以外の文字コード (EUC-JP など) を用いたい場合は、それに合わせてソース自体の文字コードを変換する必要があります。

ActiveRecordMessagesJa では、特に理由がない限り、内部の文字コードには UTF-8 を使うことをオススメします。

TransSid

続いて TransSid の機能を使ってみましょう。

PHP の人はなじみ深いと思いますが、session を cookie でなく URL などで引き回すのに使います。 日本の携帯には cookie が利用できない機種が多いため、これは携帯案件では比較的必須の機能だと思います。

url_for などの Rails の URL 生成メソッドを使うと _session_id が自動的に付与され、また form の hidden に _session_id が埋め込むことによって、session の引き回しが可能になります。

利用方法は、どこかで

 ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS[:trans_sid] = true

のように設定します。 設定するタイミングは自由なので、例えば before_filter で携帯かどうかを判別して携帯なら true にする、といった使い方も可能です。

また当然のことですが、URL に session_id を付与することによって、session_id を含む URL が漏洩するだけでセッションハイジャックが可能になってしまうので、利用の際には十分セキュリティに配慮する必要があります。

Iso2022jpMailer

最後に、Iso2022jpMailer の使い方を説明します。

ActionMailer はデフォルトでは iso-2022-jp が考慮されていないため、日本で広く使われている iso-2022-jp のメール送信に手間を要します。そこで Iso2022jpMailer の出番です。

通常 Rails では ActionMailer::Base を継承してメール送信ロジックを作るのですが、その継承する親クラスを ActionMailer::Base から Iso2022jpMailer に変更するだけで OK です。とっても簡単ですね。

具体的には

 class FooMailer < Iso2022jpMailer
   def welcome(recipient)
     recipients recipient
     from       "えきざんぷるさん <foo@example.com>"
     subject    "こんにちわ!レイルズ!"
     body       :recipient => recipient
   end
 end

のように実装するだけで、iso-2022-jp で問題なくメールが送れるようになります。かゆいところに手が届く機能ですね。

おわりに

以上で ActiveHeart に関する説明は終わりです。さくっと作った物ですが、あると便利な plugin だと思います。 日本で Rails を使うのにあったらいいな、という機能があったら是非実装してみてください。 plugin 自体はさくっと作れますので、皆さんが公開することで他の人もきっと幸せになれるはずです。

最後に、ActiveHeart のほとんどの機能のネタ元となった くまくまーさん、 Iso2022jpMailer のソースを提供してくださった drawnboy さん、 編集の moriq さん、どうもありがとうございました。

コラム - plugin の作り方

plugin とは、Rails 0.14 から導入された機能です。今までは Rails を拡張するライブラリを作成した場合、「lib にライブラリを置いて、config/environment.rb に〜を記述して云々」といった面倒な手順が必要でした。しかし plugin を利用すると、vender/plugins 以下にファイルを配置するだけで簡単に拡張することができるようになりました。ここでは around_filter を使い、X-Framework ヘッダを追加する簡単な plugin の作り方を説明します。

まずは plugin のひな形を作成します。Rails 1.4.3 から ./script/generate plugin でひな形を作成することができるので、このコマンドを利用しましょう。

$ ./script/generate plugin xframework
     create  vendor/plugins/xframework/lib
     create  vendor/plugins/xframework/tasks
     create  vendor/plugins/xframework/test
     create  vendor/plugins/xframework/README
     create  vendor/plugins/xframework/Rakefile
     create  vendor/plugins/xframework/init.rb
     create  vendor/plugins/xframework/lib/xframework.rb
     create  vendor/plugins/xframework/tasks/xframework_tasks.rake
     create  vendor/plugins/xframework/test/xframework_test.rb

いろいろ生成されました。この中で重要なのが init.rb と lib/xframework.rb です。今回はその他の Rakefile や test などの説明は割愛します。では lib/xframework.rb に X-Framework ヘッダを追加する around_filter を作ってみましょう。

 # Xframework
 class XframeworkFilter
   def before(controller)
     controller.headers['X-Framework'] = 'Ruby on Rails/' + Rails::VERSION::STRING
   end
   def after(controller); end
 end
注:
Rails 0.14.3 では Rails::Version::STRING と書く必要があります。0.14.4 ではバージョンの定数名が VERSION に変更されています。上の例は 0.14.4 に従っています。

次に init.rb でこの around_filter を実行するようにコードを記述します。

 require_dependency 'xframework'
 ActionController::Base.class_eval do
   around_filter XframeworkFilter.new
 end

以上で終了です。

./script/server で httpd を起動し、Rails のアクションにアクセスしてみます。

 $ curl -I http://localhost:3000/foo/bar
 HTTP/1.1 200 OK
 Connection: close
 Date: Fri, 09 Dec 2005 11:38:29 GMT
 Content-Type: text/html
 Set-Cookie: _session_id=466ba3c983e3a8503ec599035542e53d; path=/
 Cache-Control: no-cache
 X-Framework: Ruby on Rails/0.14.4
 Server: lighttpd/1.3.13

X-Framework ヘッダが追加されていますね。

plugin の仕組みとしては、config/environment.rb が呼ばれた後に、xframework/lib ディレクトリが $LOAD_PATH に追加され、その後 init.rb が eval で実行されます。 これらの呼び出しの順番を覚えておけば、イメージした通りに plugin が作れるでしょう。

著者について

gorou こと舘野祐一 (たての・ゆういち)

駆け出し web プログラマ。 近々 php プログラマから perl プログラマに転向するらしい (ruby は?)。 最近の執筆記事は Software Design 2005 年 12 月号の「Ruby on Rails で Ajax アプリ開発」。

  1. 詳しくは http://d.hatena.ne.jp/secondlife/20051101/1130850457 を参照