There's an echo in my head

日々のメモ。

Sinatraのpassで処理を別のルーティングに引き渡す

Sinatraで複数のルーティングにマッチすると先に宣言されたほうで処理が行われるけど、passを使うと次のルーティングに処理が引き渡される。

どのルーティングにマッチするかにはPATH_INFOが使われている*1ので、passする前にこれを書き換えることで全く別のルーティングに処理を引き渡すことができる。

get "/aaa" do
  request.path_info.gsub!("aaa", "bbb")
  pass
end

get "/bbb" do
  "Welcome to bbb!"
end

実際はpath_infoだけでなく、pathurlについてもgsub!を実行しておいたほうが安全そう。

あと、フィルターの実行条件が変わって、beforeはpass元(上での"/aaa")の条件で実行されるけど、afterはpass先(上での"/bbb")で実行されるので要注意。

追記

ルーティングの検索はアクセスのあったHTTPメソッド内で行われるので、たとえrequest.request_methodを書き換えたとしても他のメソッドのものに引き渡すことはできない。たとえばGET /aaaからGET /bbbはできても、PUT /cccはできない。

*1:process_routeを参照

このブログに出てくるコードスニペッツは、引用あるいは断りがない限りMITライセンスです。