6

我看到了一些与该主题相关的帖子,但给定的解决方案并没有真正为我澄清事情......

因此,我正在开发一个 Rails(版本 3.2.2)应用程序,该应用程序遵循 Michael Hartl 的 Ruby on Rails 教程中的设置。该应用程序有一个注销链接,直到最近它开始给我错误'没有路由匹配[GET]“/signout”'时运行良好。

这些是相关的部分:

路线.rb

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

session_controller.rb

def destroy
  sign_out
  redirect_to root_path
end

session_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>

注销重新开始工作所需要的只是从路由文件中删除 ":via => :delete"。这是正确的方法还是有更好的方法?另外,为什么没有任何 Rails 更新,链接就停止工作了?

谢谢你,亚历山德拉

根据要求,我添加了 _header.html.erb 的完整代码:

完整的_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 ***** -->
4

8 回答 8

14

这个线程有点旧,但我想我还是会分享一个解决方案,因为更多的人可能会遇到同样的问题。

在我们进行实际故障排除之前,以下是有关其工作原理的一些背景信息:

请注意,退出链接如下所示:

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

如果您查看此标记生成的源代码,您将看到:

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

注意说的部分data-method="delete"。使用直接的 HTML,这是行不通的。如果您单击该链接,您的浏览器将简单地忽略 DELETE 指令,而是向您的服务器提交一个 GET 请求(这是您当前在日志中看到的内容)。要让您的浏览器提交 DELETE 请求,您需要使用一些 JavaScript 魔法。这是 jquery_ujs.js 文件的来源(您很可能通过在浏览器中查看源代码可以看到指向该文件的链接;它应该在标题中,靠近或包含在 application.js 文件中) . 如果您查看 jquery_ujs.js 文件的内部,朝向文件的中间,您将看到以下代码:

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

换句话说,上面的代码确保您的浏览器确实提交了一个 DELETE 请求(我们不必在这里深入了解实际代码的细节)。

鉴于此背景信息,您收到错误的原因可能有两个。

  1. 您只是缺少 jquery_ujs.js 文件

  2. 您编写或包含的其他 JavaScript 代码干扰了 jquery_ujs.js 文件的所需行为

要进行故障排除,请执行以下操作:

  1. 对于 1) 加载包含退出链接的页面,然后从浏览器中选择查看源代码。确保文件 jquery_ujs.js 位于标头中(或与其余 JS 文件连接到 application.js 文件中,具体取决于您的应用程序设置)

  2. 对于 2) 在 application.js 中,删除该//=require_tree .指令。重新加载您的页面,然后单击退出链接。如果退出链接隐藏在仅适用于安装了 JavaScript 的菜单下,那么只需将退出链接的副本放在页面上其他无需 JavaScript 即可访问的位置。现在尝试点击链接——它应该可以工作。如果您不再收到路由错误,您就知道这是您的问题的原因。解决此问题的最简单方法是重新添加//=require_tree .指令,但随后从它们所在的文件夹中删除除 application.js 文件之外的所有 JavaScript 文件,然后在尝试退出链接时一一添加每个文件,直到它不再有效。这将允许您识别麻烦制造者 JavaScript 文件。确定此文件后,请尝试删除所有代码(在此链接应该再次工作),然后重新添加代码片段,直到它不再工作 - 瞧,您现在已经确定了问题的根源!请随时报告它是什么。我的猜测是,它可能是直接错误、return false;声明或stopPropagation();声明。

希望这会奏效!祝你好运。

于 2013-01-06T10:35:15.330 回答
3

由于我在 2012 年 9 月收到的答案并没有解决我的问题,因此我最终从路由文件中删除了 ":via => :delete",这使得注销链接再次起作用。

在阅读了 eriklinde 的答案后,我回到了我的代码,看看他的答案是否有帮助。jquery_ujs.js 文件没有丢失。因此,我开始研究建议的第二个可能原因。然而,当我转到 routes.rb 文件并添加 "via: :delete" 以显示"match '/signout', :to => 'sessions#destroy', via: :delete"时,注销功能继续工作没有问题。由于"via: :delete"与我之前删除的":via => :delete"不同,也许这是导致问题的原因?

于 2013-01-06T19:08:24.947 回答
2

我遇到了同样的问题,并通过重新排列 application.js 文件中的需求顺序来解决它。我的订单是这样的:

//= require jquery_ujs
//= require jquery
//= require bootstrap
//= require_tree .

现在像这样订购

//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require_tree .

我真的什么也没做。

于 2013-02-08T05:11:18.020 回答
2

我认为解决方案在这里: Rails 3 link_to (:method => :delete) not working

您的页面中是否缺少 <%= javascript_include_tag :all %> ?它应该在您的布局文件中。

于 2012-09-07T15:57:51.510 回答
0

尝试将 _header.html.erb 部分更改为

<li> 
  <%= link_to "Sign out", signout_path, :method "delete" %> 
</li> 
于 2012-09-07T16:02:33.400 回答
0

实际上,您可能缺少跨站点防伪标签。这可以解释无法通过 delete 方法删除。不知道为什么它以前工作。

将此添加到头部部分的布局文件中

火腿肠

= csrf_meta_tags

对于erb

<%= csrf_meta_tags %>
于 2012-09-07T16:31:49.517 回答
0

我的猜测是你没有安装/激活 jQuery UJS。

此处列出的关键功能之一是“从超链接发出非 GET 请求”。尝试添加gem 'jquery-rails'到您的 gemfile,从命令行运行bundle install,重新启动您的服务器,看看它是否有效!

这应该在您的 application.js 文件中(上面没有不以 //! 开头的行)

//= require jquery
//= require jquery_ujs
于 2012-09-07T18:21:28.530 回答
0

尝试这个 :

只需添加到您的 application.js

//= require jquery_ujs
于 2016-12-04T18:49:58.333 回答