Sunday, February 17, 2008

rescue_from() and Proc#bind()

Rails 2.0 の新機能に rescue_from(exception_class) という地味なやつがあります。いままでは、 ApplicationController などで rescue_action などをオーバライドして引数に与えられる exception を case ... when で処理するというわかりやすいけど、ダサイ方法で対応してきました。rescue_from を使うとこんな感じに書けます。


class UnauthorizedError < RuntimeError; end

class ApplicationController < ActionController::Base
...
before_fiter :login_required
def login_required
raise UnauthorizedError
end

rescue_from UnauthorizedError do
redirect_to login_path(:return_to => request.request_uri)
end
end


before_filter などにブロックを与える場合、そのブロックの self はそのコントローラのクラスなので、ブロックパラメータ controller を使うか、上記のようにインスタンスメソッドのシンボルを与える方法を使います。 ApplicationController で login_required のようなフィルタを追加した場合、かならず skip_filter したいケースがあるのでこの場合はいいんですけど、 before_fiter :foo; def :foo; ... end と冗長な書き方がウザイときもあります。

それと比べて、 rescue_from のブロックの中身はなぜかインスタンスメソッドと同じように書けます。Ruby 標準にはそんな機能はない思ってたのにと調べたら、秘密は ActiveSupport の Proc#bind() でした。

以上。

No comments: