IronRuby で Ruby on Rails を動かしてみました

昨年のRailsカンファレンスに続いて今年のRailsカンファレンスでは、「IronRuby on Rails」というセッションが行われました。このセッションでは、公開されたIronRuby 0.5.0とRuby on Rails 2.3.2を使って実際にRailsをIronRubyで動かしています。少し(大分かも)前から、IronRubyでRailsを動かすためのドキュメントが公開されています。このカンファレンスで何を紹介したかというサマリーが、Jimmyさんのブログで紹介されています。Railsを動かすドキュメントを使って、実際にRailsを動かしてみましたので、その手順を以下に記載していきます。

1.環境構築

IronRuby 0.5.0をダウンロードしてC:\IronRuby-0.5.0フォルダへ展開し、OneClick Installerで使ってC:\RubyへRubyをインストールしました。

2.Rails 2.3.2 の導入

  • RubyGems のアップデート
  • Ruby on Rails 2.3.2をRubyGemsを使ってインストール
 #コマンドプロンプトで作業
gem update --system
gem install rails --v2.3.2 --include-dependencies

 (注)RubyGemsを利用するために、Ruby 1.8系が必要になります。

3.環境変数の設定

  • PATH環境変数へ IronRubyのBinフォルダへのパスを追加します。
  • GEM_PATH環境変数へRubyGemsのパスを設定します。
 SET PATH=%PATH%;C:\IronRuby-0.5.0\bin
SET GEM_PATH=C:\ruby\lib\ruby\gems\1.8

 

4.IronRubyの構成ファイルである「ir.exe.config」のLibralyPathsの値にRuby1.8のライブラリパスを設定します。

 <set language="Ruby" value="..\lib\IronRuby;
       c:\ruby\lib\ruby\site_ruby\1.8\;
       c:\ruby\lib\ruby\1.8\" option="LibraryPaths" />

(注)valueの値は読みやすいように改行していますが、実際に設定する場合は改行を含めないで下さい。またir.exe.configは、IronRuby 0.5.0を展開した中のBinサブフォルダに存在します。

4.SQL Server のActiveRecord Adapter の導入

  • MS SQL Server Adapter
  • ダウンロードした「mssql_adapter.rb」を「C:\Ruby\lib\ruby\gems\1.8\gems\activerecord-2.3.2\lib\active_record\connection_adapters」フォルダーにコピーします。

(注)もちろん、SQL Serverをインストールしておく必要があります。私の場合は、SQL Server 2008 Express Editionで確認を行いました。このアダプターでは、以下のようなデータ型の対応付けが行われています。

 :primary_key => "int not null identity(1,1) primary key ",
:string      => { :name => "varchar", :limit => 255 },
:text        => { :name => "text" },
:integer     => { :name => "int" },
:float       => { :name => "float" },
:decimal     => { :name => "numeric" },
:datetime    => { :name => "datetime" },
:timestamp   => { :name => "datetime" },
:time        => { :name => "datetime" },
:date        => { :name => "datetime" },
:binary      => { :name => "varbinary", :limit => 'MAX' },
:binary      => { :name => "image" },
:boolean     => { :name => "bit" }

 

5.WEBrickに対するパッチを投入します

  • 「C\Ruby\lib\ruby\1.8\webrick\httprequest.rb」へパッチを投入します。 
  • パッチは、githubから入手します。

 パッチの内容は、2か所あります。最初に、163行目のHttpRequestクラスのto_sメソッドです。

 #      ret = @request_line.dup
#      @raw_header.each{|line| ret << line }
       ret = @request_line ? @request_line.dup : ""
       @raw_header.each{|line| ret << line } if @raw_header

次は、8行目(require)の直後に追加します。

 # IronRuby bug: IO#read seems to chop off the first char
class TCPSocket
  def read size
    recv size
  end
end

6.Railsからエンコード指定を取り除きます。2.3.2のRailsはデフォルトがUTF-8のエンコーディングです。が、IronRubyではUTF-8エンコーディングの文字列が組み合わさるとバグが発生するためです

  • 「C:\Ruby\lib\ruby\gems\1.8\gems\rails-2.3.2\lib\initializer.rb」の「initializ_encoding」メソッドの実装をコメントアウトします。
    407行目の「$KCODE='u' if RUBY_VERSION < '1.9'」をコメントにします。

ここまでで、準備が完了です。ここからは、Railsアプリケーションを作成していく作業となります。

7.新しいRailsアプリケーションを作成します

  • 「irails IronRubyOnRails」コマンドを使用します。
    「3.環境変数」を設定したコマンドプロンプトで作業を行います。

(注)成功すれば、コマンドプロンプトに「create ....」というログが表示されます。IronRubyでは、各種のコマンドの先頭に「i」というプレフィックスが付きます。インタラクティブRuby(irb)なら、「iirb」となります。これらのコマンドは、Windows向けにはBATファイルがあり、Linux向けには拡張子無しのシェルスクリプトファイルが提供されています。

8.データベースの設定を行います

  • IronRubyOnRails\config\database.ymlファイルを編集します。
 development:
  adapter: mssql
  host: (local)\SQLEXPRESS
  database: ironruby_dev
  integrated_security: true

上記のように設定するか、host、database、integrated_securityパラメータを「connection_string」パラメータで置き換えます。

続いて「ironruby_dev」という名前のデータベースをSQL Serverで作成します。SQL Server 2008 Management Studio Expressを使用するのが簡単です。
(注)このパラメータ形式は、SQL Serverをご存じな方には馴染み易いことでしょう。ADO.NETなどで、指定する接続文字列をパラメータとして指定しているのです。

9.Scaffolding を使ってサンプルのアプリケーションを作成します

  • 「ir script/generate scaffold post title:string body:text published:boolean」コマンドをIronRubyOnRailsフォルダで実行します。

(注)成功すればコマンドプロンプトに「create....」というログが表示されます。

10.アプリケーションコントローラーのバグ対応を行います。

  • 「app\controllers\posts_controller.rb」で「default_url_options」メソッドをpublicに定義します。
 class PostsController < ApplicationController
...
...
  # 私の場合は、最後に追加しました
  public :default_url_options
end

(注)この変更は、IronRubyのバグ1354に対する対応です。rails 2.3.2では、default_url_optionsメソッドがprotectedとして定義されています。IronRubyでは、publicである必要があります。publicに変更しないでWEBrickを起動すると、http リクエストに対するレスポンスが帰ってきません。default_url_optionsメソッドのエラーがコンソールに出力される場合もあります。

11.データベースのテーブルを作成します

  • 「irake db:migrate」コマンドを実行してテーブルを作成します。
 C:\IronRubyOnRails>irake db:migrate
(in C:/IronRubyOnRails)
==  CreatePosts: migrating =================
-- create_table(:posts)
   -> 0.0550s
   -> -1 rows
==  CreatePosts: migrated (0.0990s) ========

成功すれば上記のように「create table...」などのログがコンソールに出力されます。失敗すると以下のように「System::Text::EncoderFallbackException」が出力されます。

 C:\IronRubyOnRails>irake db:migrate
(in C:/IronRubyOnRails)
rake aborted!
rake aborted!
mscorlib:0:in `GetBytes': 値が有効な範囲にありません。
          (System::Text::EncoderFallbackException)
        from :0:in `write'
        from :0:in `puts'
.....

失敗した場合は、「config\database.yml」の設定内容を見直してください。host: (local)\SQLEXPRESSなどを書き間違えると、このエラーが出力されます(私も書き間違いをしていて、このエラー原因を探すのに苦労しました)。

11.WEBrickを起動してテストを行います

  • 「ir script/server」コマンドを実行します。
 C:\IronRubyOnRails>ir script/server
=> Booting WEBrick
=> Rails 2.3.2 application starting on https://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2009-06-09 17:14:17] INFO  WEBrick 1.3.1
[2009-06-09 17:14:17] INFO  ruby 1.8.6 (2008-05-28) [i386-mswin32]
[2009-06-09 17:14:17] INFO  WEBrick::HTTPServer#start:
                                            pid=4568 port=3000

 

正常に起動すれば、上記のようなログが出力されます。しかしながら、私の環境(Windows Vista with SP2)では少し時間がかかります。

  • ブラウザで「https://localhost:3000/」へアクセスすれば、railsのページが表示されることでしょう。
    rails aborted

  • 「about your application's environment」をクリックします。
    about application environment 
    正常に実行されれば実行環境が上記のように表示されます。が、この情報はRailsのInfoControllerが処理する関係で、IronRubyとは表示されることはありません。あくまでも、Ruby 1.8系として表示されるだけです。

  • 次に「https://localhost:3000/posts」へブラウザでアクセスします。
    Listing posts 
    上記のようにpostsテーブルの一覧が表示されます。new postsのリンクをクリックしてデータを追加していけば、問題なく動作することを確認していくことができます。
    この時点で、コンソールを確認すると以下のようなログが出力されていました。

     Processing Rails::InfoController#properties
     (for 127.0.0.1 at 2009-06-09 17:21:5) [GET]
    Completed in 584ms (View: 189, DB: 0) | 200 OK
                 [https://localhost/rails/info/proerties]
    
    
    Processing PostsController#index
     (for 127.0.0.1 at 2009-06-09 17:25:21) [GET]
    Rendering template within layouts/posts
    Rendering posts/index
    Completed in 735ms (View: 540, DB: 0) | 200 OK
                [https://localhost/posts]
    

    これらのログが表示されるのが、私の環境では少し遅くなっています。ブラウザでは問題なく動作しているのですが、WEBrickのログ出力が遅くなるという問題があるようです。もしかすると、環境依存かもしれません。

ここまでの動作で、IronRubyを使ってRuby on Rails 2.3.2が動作していることを確認することができました。データベースとしては、SQL Serverです。まだまだパフォーマンス的な問題や、バグが残っているにしてもIronRubyによる Ruby on Railsの実現が近くなってきたのを感じ取ることができます。是非、皆さんも試してみてください。そしてバグを見つけたら、フィードバックをしてください。

PS.昨年のRailsカンファレンスでもIronRubyでrailsを動かしていますが、日本では情報が少ないように感じています。是非、皆さんも動かしてみてください。

追記:WEBrickへのパッチを投入するファイル名を追加しました。