エルミナージュ2(続) ― 2010/02/19
……おかしい、なぜ10日で50時間もプレイ時間が増えているのだろう?
寝落ちはしてないはずなのだけど……。
Rails Metal の URIマッピング ― 2010/02/26
発端
passenger + Rack 環境にアプリを置こうと思ったのだけど、 いろいろあって、「ActiveRecord があった方が良くね?」という意見が発生。
「それだったら、Rails Metal で良くね?」という結論が、脳内会議で決議された訳だけど、そこで悩んだのが、URIマッピングのルールが良く判らない、という点。
ソースはあんまり見てない(特にroutes関係)なので、あまり信用しない方が良いけど、何かの役に立つかも知れないので、晒しておく。
テンプレート
$ ./script/generate metal foobar
の結果作成される app/metal/foobar.rb のテンプレートは
# Allow the metal piece to run in isolation require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails) class Foobar def self.call(env) if env["PATH_INFO"] =~ /^\/foobar/ [200, {"Content-Type" => "text/html"}, ["Hello, World!"]] else [404, {"Content-Type" => "text/html"}, ["Not Found"]] end end end
こんな感じになる。 これは(require行とその作用を除けば)、非常に単純なRackアプリケーションそのものなので、 詳細は省略する。
これで、
$ ./script/server & $ curl http://localhost:3000/foobar Hello, World!
foobar 以下のURIがこの metal で処理されていることが判る。
routes.rb ?
Rails アプリケーションのURI情報の設定なら、config/routes.rb が正道だ、と思ったが、 どうも routes.rb には metal 関係のキーワードは定義されていない。
ルーティング情報はどこに?
となると、怪しいのは
if env["PATH_INFO"] =~ /^\/foobar/
この if文だという訳で、regexpを書き換えたりしてみたところ、どうもこいつがルーティング情報らしいことが判明。
# Allow the metal piece to run in isolation require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails) class Foobar def self.call(env) if env["PATH_INFO"] =~ /^\/hogehoge/ [200, {"Content-Type" => "text/html"}, ["Hello, World!"]] else [404, {"Content-Type" => "text/html"}, ["Not Found"]] end end end
だと
$ curl http://localhost:3000/foobar (略) Routing Error (略) $ curl http://localhost:3000/hogehoge Hello, World!
になる。
まとめ
- metal は routes.rb に書いた規則よりも前に実行される。
- metal は全てのURIに対して実行される。
- metal が、404のレスポンスを返した場合は、他の metal(あれば)、routes.rb の規則の適用の順にリクエストが取り回される。
- 複数の metal が存在する場合の実行順は未定義(ファイルのiノード順っぽい)
ということみたいだ。
演繹できる事実として、同名の metal と controller が居た場合は metal が勝つのと、 controller に落ちるまでには metal が全て実行されるので、極端に metal のクラスが多い場合は要注意かも知れない。
あと、passenger と共に使用する場合は、metal の中で、request.body() とかやってしまった後に、404で次の metal や controller に処理を 回すと大変な事になるような気がする。
(passenger の Rackインターフェイスに入ってくる request.body()はrewindableなオブジェクトではないため)
追記
長々と書いた後で、config/config.ru に rackup用のconfigが書けることに気がついた。
ここなら、 マッピングルールを自在に書ける。
Rails Metal と Controller のセッション共有 ― 2010/02/26
ここが詳しい。
Controller クラスのインスタンスメソッド session で参照できる Hash と同じものが、 Metal クラスでは env['rack.session'] で参照できる。
(env は call の引数)
パーシー・ジャクソンとオリンポスの神々 ― 2010/02/27
RPG好きなら、結構楽しめると思う。
ただ、映画として見ると、かなり厳しい。
ストーリーらしいストーリーはないし、設定というか物語の御膳立てもかなり破綻してる。
主人公は努力したりしない(危なくなったらパパンが助言をくれる)し、まあなんと言うか、「Aボタン連打で進行するイベント」の連続だ。
小ネタでにんまりとできるところは随所にあるけど、2時間拘束された代償になるほどのカタルシスは欠片もない。
そんなところも含めて、FFとかDQとかの和製コンシューマRPGっぽい。
いやまあ、僕は結構楽しかったですよ。
最近のコメント