Routing for sessions#destroy action

2019-06-28 02:06发布

I'm linking to the destroy action for the Sessions controller like this:

<%= link_to "Sign out", session_path, method: :delete  %>

Routes.rb:

resources :sessions, only: [:new, :create, :destroy]

Rails complains about the link above:

No route matches {:action=>"destroy", :controller=>"sessions"} missing required keys: [:id]

How do I link to the destroy action and keeping the REST/resource methodology in Rails when there's no object ID to provide for the link?

5条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-06-28 02:21

destroy is a member route, you need to pass id in the params to make it work, but you can do this to convert it to a collection route

resources :sessions, only: [:new, :create] do
  delete :destroy, on: :collection
end

Hope that helps!

查看更多
▲ chillily
3楼-- · 2019-06-28 02:31

By default destroy method expects id, which should be pass with the link. For Ex. you are destroying session for logged in user, then you have to pass id or session of logged-in user, in this case, your link should be like this, <%= link_to "Sign out", session_path(user.id), method: :delete %> or if your purpose is to just delete/clear session only then you need to change in route.

resources :sessions, only: [:new, :create]
delete '/session', to: 'sessions#destroy'

If you want both types of link(In which we may pass ID or not), then you should try this route. delete '/session(/:id)', to: 'sessions#destroy'

查看更多
何必那么认真
4楼-- · 2019-06-28 02:34

You need to pass the session resource to that route, like so:

<%= link_to "Sign out", session_path(session), method: :delete  %>

Rails show and delete actions require a resource.

查看更多
一夜七次
5楼-- · 2019-06-28 02:40

It is best to treat the routes to your sessions controller as a singular resource

routes.rb

resource :sessions

Doc: http://guides.rubyonrails.org/routing.html#singular-resources

This will give you a route that you can use without ID's

DELETE /sessions sessions#destroy

查看更多
一夜七次
6楼-- · 2019-06-28 02:44

You need to change the path, which in your case can be /users/sign_out or sessions/sign_out and not /sessions with a DELETE method.

Take a look at devise's session destroy action and the route.

So, you could use something like

    resource :session do
      delete :destroy, path: 'sign_out', as: "destroy"
    end

Which will create path /session/sign_out which points to sessions#destroy and you can call it in your views as destroy_session_path.

查看更多
登录 后发表回答