6

I saw a few postings related to this topic, but the given solutions did not really clarify things for me ...

So, I am working on a rails (version 3.2.2) application that followed the setup from Michael Hartl's Ruby on Rails tutorial. The application has a signout link, which worked well until recently, when it started giving me the error 'No route matches [GET] "/signout"'.

These are the relevant pieces:

routes.rb

match '/signout' => 'sessions#destroy', :via => :delete

sessions_controller.rb

def destroy
  sign_out
  redirect_to root_path
end

sessions_helper.rb

def sign_out
  current_user = nil
  cookies.delete(:remember_token)
end

_header.html.erb

<li>
  <%= link_to "Sign out", signout_path, :method => :delete %>
</li>

All it takes for the signout to start working again is the removal of ":via => :delete" from the routes file. Is this the right approach or is there a better one? Also, why did the link stop working without any rails update?

Thank you, Alexandra

On request, I added the full code for the _header.html.erb:

full _header.html.erb

<!-- ***** Initialized: Listing 5.24 ***** -->
<!-- ***** Updated: Listing 8.24 ***** -->
<!-- ***** Updated: Listing 9.7 ***** -->
<!-- ***** Begin: Listing 9.28 ***** -->
<header>
<header class="navbar navbar-fixed-top">
  <div class="navbar-inner">
    <div class="container">
      <% if signed_in? %>
        <%= link_to "project manager", about_path, id: "logo" %>
      <% else %>
        <%= link_to "project manager", root_path, id: "logo" %>
      <% end %>
      <nav>
        <ul class="nav pull-right">
          <!--li><%= link_to "Home", root_path %></li-->
          <% if signed_in? %>

<% if Rails.env.development? %>
            <li><%= link_to "Overview", overview_path %></li> 
<% end %>         
<% if Rails.env.development? %>
            <li id="fat-menu" class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Projects <b class="caret"></b>
              </a>
              <ul class="dropdown-menu">
              <li><%= link_to "Status", projects_path %></li>
              <li><%= link_to "Dev View", dev_projects_path %></li>
              </ul>
            </li>
<% else %>
          <li><%= link_to "Projects", projects_path %></li>
<% end %>
<% if Rails.env.development? %>
            <li><%= link_to "Teams", teams_path %></li> 
<% end %>
<% if Rails.env.development? %>
            <li id="fat-menu" class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Tasks <b class="caret"></b>
              </a>
              <ul class="dropdown-menu">
              <li><%= link_to "Status", tasks_status_path %></li>
              <li><%= link_to "Tree", tasks_tree_path %></li>
              <li><%= link_to "Dev View", dev_tasks_path %></li>
              </ul>
            </li>
<% else %>
            <li id="fat-menu" class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Tasks <b class="caret"></b>
              </a>
              <ul class="dropdown-menu">
              <li><%= link_to "Status View", tasks_status_path %></li>
              <li><%= link_to "Tree View", tasks_tree_path %></li>
              </ul>
            </li>
<% end %>

<% if Rails.env.development? %>
            <li id="fat-menu" class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Reports <b class="caret"></b>
              </a>
              <ul class="dropdown-menu">
              <li><%= link_to "Project Progress", analysis_path %></li>
              <li><%= link_to "Revision History", history_path %></li>
              </ul>
            </li>              
<% else %>
            <li id="fat-menu" class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Reports <b class="caret"></b>
              </a>
              <ul class="dropdown-menu">
              <li><%= link_to "Revision History", history_path %></li>
              </ul>
            </li>
<% end %>
<% if Rails.env.development? %>
            <li><%= link_to "Help", help_path %></li>
<% end %>
            <li id="fat-menu" class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Account <b class="caret"></b>
              </a>
              <ul class="dropdown-menu">
<% if current_user.admin? %>
                <li><%= link_to "Admin", users_path %></li> 
<% end %>
<% if Rails.env.development? %>
                <li><%= link_to "Profile", current_user %></li>
<% end %>
                <li><%= link_to "Settings", edit_user_path(current_user) %></li>
                <li class="divider"></li>
                <li>
                  <%= link_to "Sign out", signout_path, :method => :delete %>
                </li>
              </ul>
            </li>
          <% else %>
            <li><%= link_to "Sign in", signin_path %></li>
          <% end %>
        </ul>
      </nav>
    </div>
  </div>
</header>
<!-- ***** End: Listing 9.28 ***** -->
AndraD
  • 2,830
  • 6
  • 38
  • 48
  • Did you get this fixed? What was the problem in the end? – stephenmurdoch Oct 22 '12 at 23:54
  • I ended up using the fix mentioned in my question (removing the ":via => :delete" from the routes file) - it works, but I am not sure what the problem really was and did not get the time to revisit this issue ... – AndraD Oct 23 '12 at 18:08
  • http://stackoverflow.com/questions/23368994/no-route-matches-get-logout-rails – Keon Oct 09 '14 at 06:41

8 Answers8

14

This thread is a bit old, but I thought I'd share a solution anyway as more people might be having the same problem.

Here is some background information on how this works before we get into the actual troubleshooting:

Notice that the Sign Out link looks as follows:

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

If you look at the source code generated by this tag, you will see this:

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

Notice the part that says data-method="delete". With straight HTML, this won't work. If you click the link, your browser will simply ignore the DELETE instruction and instead submit a GET request to your server (this is what you are currently seeing in your log). To get your browser to submit a DELETE request, you will need to use some JavaScript magic. This is where the jquery_ujs.js file comes in (you will most likely be able to see a link to this file by Viewing Source in your browser; it should be in the header, close to, or included within the application.js file). If you look inside the jquery_ujs.js file, towards the middle of the file, you will see the following code:

// Handles "data-method" on links such as:
// <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a>

In other words, the code above makes sure that your browser actually does submit a DELETE request (we don't have to get into the details of the actual code here).

Given this background information, there are two possible reasons why you are getting your error.

  1. You are simply missing the jquery_ujs.js file

  2. Other JavaScript code you have written or included is interfering with the desired behavior of the jquery_ujs.js file

To troubleshoot, do as follows:

  1. For 1) Load the page that contains your Sign Out link and select View Source from your browser. Make sure that the file jquery_ujs.js is in the header (or concatenated with the rest of your JS files into the application.js file, depending on your application settings)

  2. For 2) In application.js, remove the //=require_tree . directive. Reload your page, and click the Sign Out link. If the Sign Out link is hidden under a menu that only works with your JavaScript installed, then just put a duplicate of the Sign Out link somewhere else on your page where it is accessible without JavaScript. Now try clicking on the link - it should hopefully work. If you are no longer getting the routing error, you know that this was the cause for your problem. The easiest way to troubleshoot this is to add back the //=require_tree . directive, but then to remove all your JavaScript files except the application.js file from the folder where they reside, and then to add back each file one by one, while you try the Sign Out link, until it no longer works. This will allow you to identify the troublemaker JavaScript file. Once you have identified this file, try removing all code (upon which the link should work again) and then adding back pieces of the code until it no longer works - voila, you have now identified the root of the problem! Please feel free to report back what it was. My guess is that it could be either a straight up error, a return false; statement, or a stopPropagation(); statement.

Hopefully this will work! Good luck.

AndraD
  • 2,830
  • 6
  • 38
  • 48
eriklinde
  • 431
  • 6
  • 7
  • Just helped tremendously! This is EXACTLY the kind of issue that keeps my noobness going for days! Instead, I saw your write-up and it was fixed in 5 minutes. Can't thank you enough! – codenoob Sep 28 '14 at 16:49
3

Since the answers that I received in September 2012 did not solve my problem, I just ended up removing ":via => :delete" from the routes file, which made the signout link work again.

After reading eriklinde's answer, I went back to my code to see if his answer would help. The jquery_ujs.js file was not missing. So, I started looking into the second possible reason that was suggested. Nevertheless, when I went to the routes.rb file and added "via: :delete" to have a line reading "match '/signout', :to => 'sessions#destroy', via: :delete", the signout functionality continued working without a problem. Since "via: :delete" is different than ":via => :delete", which I previously removed, maybe this was causing the problem?

AndraD
  • 2,830
  • 6
  • 38
  • 48
2

I think the solution is here: Rails 3 link_to (:method => :delete) not working

Are you missing <%= javascript_include_tag :all %> in your page? It should go in your layout file.

Community
  • 1
  • 1
Yoni Baciu
  • 2,667
  • 1
  • 22
  • 28
  • Can you add :confirm => "Are you sure?" to the link_to? What happens when you click the link then? – Yoni Baciu Sep 07 '12 at 19:47
  • With `<%= link_to "Sign out", signout_path, :method => :delete, :confirm => "You sure?" %>`, the exact same thing happens (I get the same error). – AndraD Sep 07 '12 at 20:04
  • If you did not get a confirmation popup then something is wrong with the javascript. Maybe you have other js files that you are loading that are messing things up. Can you post the layout file here? – Yoni Baciu Sep 07 '12 at 22:10
  • Thanks but I meant the layout file (the master html page where all the javascrript, css etc is included. – Yoni Baciu Sep 08 '12 at 18:48