Boss Nass
Boss Nass

Reputation: 3522

Unable to log out of clearance gem

I have recently move my project away from the somewhat bloat devise to clearance, though I am experiencing troubles when attempting to log out

I am currently get the error of the route not existing

No route matches [GET] "/sign_out"

routes

resources :passwords, controller: "clearance/passwords", only: [:create, :new]
  resource :session, controller: "clearance/sessions", only: [:create]

  resources :users, controller: "clearance/users", only: [:create] do
    resource :password,
      controller: "clearance/passwords",
      only: [:create, :edit, :update]
  end

  get "/sign_in" => "clearance/sessions#new", as: "sign_in"
  delete "/sign_out" => "clearance/sessions#destroy", as: "sign_out"
  get "/sign_up" => "clearance/users#new", as: "sign_up"

  constraints Clearance::Constraints::SignedIn.new do
    root :to => 'shopping/merchants#index', as: :signed_in_root
  end

  constraints Clearance::Constraints::SignedOut.new do
    root to: 'clearance/sessions#new'
  end

view

= link_to sign_out_path, method: :delete, class: 'mdl-navigation__link' do
    i.material-icons> exit_to_app
    = t('.log_out')

Upvotes: 0

Views: 489

Answers (2)

nickj
nickj

Reputation: 100

I thought I'd follow up on this with a little more insights for anyone who found themselves here still wondering exactly what is behind this.

As suggested by Derek, to get this sorted, you'll need to use the button_to instead of link_to, as follows:

<%= button_to "Sign Out", sign_out_path, method: :delete %>

Why can't I just use link_to?

So more insights into this are delivered by this previous SO. Essentially, you can't make a link operate as a DELETE method, only GET.

If you have a look at how link_to is actually rendered in HTML on the page (after Ruby works its magic), you'll see the following:

<a rel="nofollow" data-method="delete" href="/sign_out">Sign out</a>

And it's clear that data-method="delete" is still not going to cut it, and still runs the request as GET.

But I don't want a button, I want a link?

Your best bet is to look at some CSS on the element to get it back to looking like a link, otherwise, you'll need to go the Javascript route.

Non-RESTFUL Clearance Centric Dirty Hack - Not Advised!

Using link_to, change your routes.rb where the clearance route currently says:

  delete     "/sign_out" => "clearance/sessions#destroy", as: "sign_out"

to:

  get     "/sign_out" => "clearance/sessions#destroy", as: "sign_out"

It'll route the GET request to the destroy action on the Clerance controller. I dare say this is not advised and Derek could support why this was not supported in the first place (Devise gem does support this dirty hack)

Upvotes: 0

Derek Prior
Derek Prior

Reputation: 3517

The message is telling you there is not get route for sign_out, which is correct. You must do a delete. This means, despite your efforts with method: :delete, the link is executing a get request. There's something about your link_to that is not correct. It likely has to do with passing method while using the block form of link_to.

Try:

<%= button_to "Sign Out", sign_out_path, method: :delete %>

If that works, try:

<%= link_to "Sign Out", sign_out_path, method: :delete %>

If both of those work, then the issue is indeed with the way you're using the block form of the link_to helper and has nothing to do with Clearance.

Upvotes: 0

Related Questions