Rails: namespace と subdomain を用いたルーティング

example.com でアクセスされた場合と m.example.com でアクセスされた場合で、異なるルーティングを適用したい場合、


scope constraints: { subdomain: '' } do
resource :session
end
scope constraints: { subdomain: 'm' }, module: 'mobile' do
resource :session do
get :logoff
end
end

みたいに書きます。

こうすると http://m.example.com/session/new にアクセスした時に Mobile::SessionsController コントローラの new アクションが呼ばれるわけです。

しかし、この書き方には名前空間を分けられないという問題があります。

example.com 向けのHTMLテンプレートの中で誤って


link_to 'ログオフ', :logoff_session

と書いてもエラーにならず、実際にクリックして初めて RoutingError が出ます。そんなに深刻な問題ではないのですが、ちょっと気持ちが悪いですね。

きちんと分けたい場合は、次のように書きます:


scope constraints: { subdomain: '' } do
resource :session
end
namespace 'mobile', path: nil do
scope constraints: { subdomain: 'm' } do
resource :session do
get :logoff
end
end
end

Mobile::SessionsController の logoff アクションへのハイパーリンクを生成するには、


link_to 'ログオフ', :logoff_mobile_session

のように書くことになりちょっと面倒ですが、


link_to 'ログオフ', :logoff_session

と書いたときに例外NoMethodErrorを出してくれます。