RailsでページによってSingOutのURLが変わってしまった件
Ruby on Rails はviewの共通テンプレートがあり、そこにsign in / out のリンクをつけることが多いと思います。
ただしroutingの設定によっては思わぬURLが生成されることもあるので注意が必要です。
次のようなリンクを${RAILS_ROOT}/app/view/layout の共通テンプレートファイルに書いていました。
<%= link_to t('consumer.header.signout'), { :controller => :sessions, :action => :destroy }, :confirm => t('consumer.header.signout_confirmation'), :method => :delete %>
商品詳細ページ以外で生成されるURLは次のようなもの。
/consumer/sessions/destroy
商品詳細ページでヘッダー部分のsign outをクリックすると、↓のようなエラーが起きました!
Processing Consumer::SessionsController#1137 (for XXX.XXX.XXX.XX at 2013-05-13 11:19:52) [GET] 2013/05/13 11:19:52 [INFO] Parameters: {"action"=>"1137", "controller"=>"consumer/sessions"} ・・・ 2013/05/13 11:19:52 [ERROR] ActionController::UnknownAction 2013/05/13 11:19:52 [ERROR] No action responded to 1137.
おかしいなーと思って、rake routesしてみると、、
$ rake routes | grep session consumer_sessions POST /consumer/sessions(.:format) {:controller=>"consumer/sessions", :action=>"create"} new_consumer_session GET /consumer/sessions/new(.:format) {:controller=>"consumer/sessions", :action=>"new"} consumer_session DELETE /consumer/sessions/:id(.:format) {:controller=>"consumer/sessions", :action=>"destroy"}
商品詳細ページで生成されるURLはこんな↓になっていました。
/consumer/sessions/1137
DELETE の /sessions/:id のところの「:id」が、商品詳細ページに遷移するときのパラメータのid( "id"=>"1137")を拾ってあんなURLを作ってしまっていたんですね。。
- 商品詳細ページへ遷移するときのログ。
Processing Consumer::ItemsController#show (for XXX.XXX.XXX.XX at 2013-05-13 19:46:06) [GET] Parameters: {"action"=>"show", "id"=>"1137", "controller"=>"consumer/items"}
対処法
route.rbを次のように修正して、ルーティング設定を見直しました。
map.namespace(:consumer) do |consumer| ・・・ consumer.signout '/sessions/destroy', :controller => :sessions, :action => :destroy <= 追加 #consumer.resources :sessions, :except => [:index, :edit, :show, :update] <= 元々 consumer.resources :sessions, :except => [:index, :edit, :show, :update, :destroy] <= 修正
rake routesしてみると↓のようになり、 無事全ページでsign outのURLが /consumer/sessions/destroy になりました。
$ rake routes | grep session consumer_signout /consumer/sessions/destroy {:controller=>"consumer/sessions", :action=>"destroy"} consumer_sessions POST /consumer/sessions(.:format) {:controller=>"consumer/sessions", :action=>"create"} new_consumer_session GET /consumer/sessions/new(.:format) {:controller=>"consumer/sessions", :action=>"new"}
まとめ
idを伴わないdestroyをする場合は、routingが正しく設定されているか、要確認!