我看到了一些与此主题相关的帖子,但给定的解决方案并没有真正为我澄清事情......
所以,我正在开发一个rails(版本3.2.2)应用程序,该应用程序遵循Michael Hartl的Ruby on Rails教程中的设置。该应用程序有一个注销链接,直到最近,它开始给我错误'没有路由匹配[GET]“/注销”'。
以下是相关内容:
的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>
注销再次开始工作所需要的是从路径文件中删除“:via =&gt;: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 ***** -->
答案 0 :(得分: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文件的来源(您很可能通过浏览器中的Viewing Source查看该文件的链接;它应该位于头文件中,靠近或包含在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请求(我们不必在此处了解实际代码的详细信息)。
鉴于此背景信息,您可能会收到错误的原因有两个。
您只是缺少jquery_ujs.js文件
您编写或包含的其他JavaScript代码会干扰所需的代码 jquery_ujs.js文件的行为
要进行故障排除,请执行以下操作:
对于1)加载包含“注销”链接的页面,然后从浏览器中选择“查看源”。确保文件jquery_ujs.js位于标题中(或者将其他JS文件连接到application.js文件中,具体取决于您的应用程序设置)
For 2)在application.js中,删除//=require_tree .
指令。重新加载您的页面,然后单击“注销”链接。如果Sign Out链接隐藏在仅适用于您安装的JavaScript的菜单下,那么只需在页面上的其他位置放置一个Sign Out链接的副本,即可在不使用JavaScript的情况下访问它。现在尝试点击链接 - 它应该有用。如果您不再收到路由错误,则表示这是导致问题的原因。解决此问题的最简单方法是添加//=require_tree .
指令,然后从它们所在的文件夹中删除除application.js文件之外的所有JavaScript文件,然后逐个添加每个文件,当您尝试注销链接时,直到它不再有效。这将允许您识别troublemaker JavaScript文件。一旦你确定了这个文件,尝试删除所有代码(链接应该再次运行),然后添加代码片段,直到它不再有效 - 瞧,你现在已经确定了问题的根源!请随时报告它是什么。我的猜测是它可能是一个直接错误,return false;
语句或stopPropagation();
语句。
希望这会奏效!祝你好运。
答案 1 :(得分:3)
由于我在2012年9月收到的答案没有解决我的问题,我最终从路径文件中删除了“:via =&gt;:delete”,这使得注销链接再次起作用。
在阅读了eriklinde的回答之后,我回到了我的代码,看看他的答案是否会有所帮助。 jquery_ujs.js文件没有丢失。所以,我开始研究建议的第二个可能的原因。然而,当我去routes.rb文件并添加“via :: delete”以读取“匹配'/注销',:to =&gt;'sessions#destroy',通过:: delete” ,注销功能继续正常运行。由于“via :: delete”与“:via =&gt;:delete”不同,我之前删除了,这可能导致问题?
答案 2 :(得分:2)
我认为解决方案在这里: Rails 3 link_to (:method => :delete) not working
您是否遗漏&lt;%= javascript_include_tag:所有%&gt;在你的页面?它应该放在你的布局文件中。
答案 3 :(得分:2)
我遇到了同样的问题并通过重新排列application.js文件中的需求顺序来修复它。我的订单是这样的:
//= require jquery_ujs
//= require jquery
//= require bootstrap
//= require_tree .
现在按此订购
//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require_tree .
我实际上什么也没做。
答案 4 :(得分:0)
尝试将_header.html.erb部分更改为
<li>
<%= link_to "Sign out", signout_path, :method "delete" %>
</li>
答案 5 :(得分:0)
实际上,您可能错过了跨站点伪造保护标记。这将解释无法通过删除方法删除。不知道为什么它以前工作。
将其添加到头部
中的布局文件中for haml
= csrf_meta_tags
对于erb
<%= csrf_meta_tags %>
答案 6 :(得分:0)
我的猜测是你不知道你没有安装/活动jQuery UJS。
here列出的一个主要功能是“从超链接发出非GET请求”。尝试将gem 'jquery-rails'
添加到您的gemfile,从命令行运行bundle install
,重新启动服务器,看看它是否有效!
这应该在你的application.js文件中(上面没有不以//开头的行!)
//= require jquery
//= require jquery_ujs