【问题标题】:Devise: Why doesn't my logout link work?设计:为什么我的注销链接不起作用?
【发布时间】:2011-08-04 18:11:40
【问题描述】:

问题:简而言之,当我尝试将注销链接安装到我的应用程序时,它无法正常工作。这是我能想到的尽可能多的上下文(如果你想要别的,请戳我)......

我在 haml 视图中得到了这个:

= link_to("Logout", destroy_user_session_path, :method => :delete)

它在视图中生成:

<a href="/users/sign_out" data-method="delete" rel="nofollow">Logout</a>

我验证了在我的 config/initializers/devise.rb 我有这个设置未注释且正确:

config.sign_out_via = :delete

我验证了以下路线:

destroy_user_session DELETE /users/sign_out(.:format) {:action=>"destroy", :controller=>"devise/sessions"}

我的 routes.rb 中也有一些诡计,我怀疑这与我的问题有关:

devise_for :users, :controllers => {:sessions => "devise/sessions", :registrations => "users"}
resources :users

最后一点是因为我想在自己的控制器中管理(编辑、创建和删除)用户。

我得到的错误信息如下:

ActiveRecord::RecordNotFound in UsersController#show

Couldn't find User with ID=sign_out
Rails.root: /home/jaydel/projects/mbsquared-projects/Wilson-Goldrick

app/controllers/users_controller.rb:16:in `show'

在我的服务器日志中,我看到了这个请求:

Started GET "/users/sign_out" for 127.0.0.1 at 2011-08-04 13:08:51 -0500
  Processing by UsersController#show as HTML
  Parameters: {"id"=>"sign_out"}

有人有什么想法吗?

【问题讨论】:

    标签: ruby-on-rails devise


    【解决方案1】:

    在 REST 方面解决此问题的正确方法是将您的注销链接更改为使用 DELETE 方法。这是一个非常简单的修复,改变这个:

    link_to "Log out", destroy_user_session_path
    

    到这里:

    link_to "Log out", destroy_user_session_path, :method => :delete 
    

    【讨论】:

      【解决方案2】:

      当我从 application.js 删除这一行时,我遇到了与 rails 3.2 相同的问题:

      //= require jquery_ujs
      

      所以,我认为如果您的application.js 中没有此行,则必须将其插入。

      PS。这种行为意味着jquery 的rails 适配器不起作用。因此,您应该确保它是否已加载到浏览器的 html 中。您应该在开发模式下对其进行测试,因为您将在生产环境中压缩 js,并且在那里很难找到。

      【讨论】:

      • 非常感谢这篇文章和解决方案。我在这个确切的问题上花费了至少 10 小时,但我完全不知道它来自哪里(这是问题所在,错误没有帮助)!!
      • 不仅 //= 需要 jquery_ujs,而且 //= 也需要 jquery
      • 啊——我刚刚添加了一个引导主题,它擦除了对 jquery_ujs 的引用,很好的答案,谢谢。
      【解决方案3】:

      问题在于您的日志中的注销请求是 GET 请求。

      Started GET "/users/sign_out"
      

      但是退出路由是一个DELETE

      destroy_user_session DELETE /users/sign_out(.:format) 
      

      您收到异常的原因是它与resources :users 创建的路由之一混淆,类似于

      edit_user GET /users/(:id)(.:format) {:action=>"edit", :controller=>"users"}
      

      基本上 'sign_out' 被误认为是 id。

      我不确定为什么删除链接没有作为 DELETE 请求通过。虽然变了

      config.sign_out_via = :delete
      

      成为:get 可能会解决问题。

      【讨论】:

      • 这不是一个好主意。您正在启用 CSRF 攻击。当状态发生变化时,应该使用 POST 和 DELETE。确保您的布局中包含jquery_ujs.js
      • 正如 Tombart 所说,这不是解决此问题的 Restful 方式。更改状态时应使用 POST 或 DELETE。
      • 是的,我将他的回答读作“应该删除,而不是获取,但如果您坚持以获取方式执行,这可能会奏效”。我将其更改为删除,世界变得更快乐。
      • 一旦您的用户使用预取链接(即 GET 请求)的浏览器,该用户的浏览器就会自动退出该用户。
      【解决方案4】:

      两者都需要
      link_to "Log out", destroy_user_session_path, method: :delete

      && 这些包含在 application.js 中

      //= require jquery
      //= require jquery_ujs
      

      。显然,如果由于某种原因它不存在,请不要忘记将其添加到 Gemfile。

      gem 'jquery-rails'

      【讨论】:

        【解决方案5】:

        这是一个老问题,但公认的答案不是解决此问题的正确方法(尽管它是对问题的良好诊断)。

        当我今天遇到这个问题时,我的路线文件显示为:

          root :to => 'welcome#index' 
        
          resources :users    
          devise_for :users
        

        正如 Olives 所提到的,资源声明只是导致 /users/anything 出错。我只需要颠倒我的路线的顺序......

         root :to => 'welcome#index' 
        
          devise_for :users
          resources :users
        

        【讨论】:

          【解决方案6】:

          需要使用 jQuery 来执行带有 DELETE 的请求。确保您没有从 application.js 中删除它。

          【讨论】:

          • 这不是真的:Rails 通过添加隐藏的_method 输入来启用类似删除的请求。可以使用表单而不使用 JavaScript 注销。请参阅我的答案以了解如何使用它。
          【解决方案7】:

          由于 OP 提到了设计并且这个问题也发生在我身上,我只是想插话。当你不想使用 jQuery_ujs 时,@Ross Allen 有正确的答案。 Rails 提供了一些帮助程序来解决这个问题,而无需 jQuery。

          这是 Ross 的答案,但使用的是 Devise 的 current_user 模型:

          <%= form_for(current_user,
              url: destroy_user_session_path, html: { method: :delete }) do |f| %>
              <%= f.submit "Log out" %>
          <% end %>
          

          或者更简洁的button_to helper 创建类似的表单:

          <%= button_to "Log out", destroy_user_session_path, method: :delete %>
          

          【讨论】:

          • 这和添加 rails-ujs 为我解决了这个问题。非常感谢。
          【解决方案8】:

          这是一个老问题,但我想要一种不需要 JavaScript 的方法。 Rails 启用“删除”之类的请求,隐藏输入将method 设置为delete。使用真实的&lt;form&gt;,并让 Rails 生成必要的隐藏输入:

          <%= form_for(resource, as: resource_name,
              url: destroy_user_session_path, html: { method: :delete }) do |f| %>
            <%= f.submit "Log out" %>
          <% end %>
          

          上面会产生类似的东西:

          <form accept-charset="UTF-8" action="/users/sign_out" method="post">
            <div style="display:none">
              <input name="utf8" type="hidden" value="✓">
              <input name="_method" type="hidden" value="delete">
              <input name="authenticity_token" type="hidden" value="1234">
            </div>
            <input name="commit" type="submit" value="Log out">
          </form>
          

          【讨论】:

            【解决方案9】:

            我已经检查了所有这些解决方案,但没有人为我工作。最后我发现在 header 中我删除了两行,包括 application tags 和 csrf meta

            所以,如果有人在这一点上没有解决这个问题 - 检查您是否在页面标题中(HAML 表示法)

            = javascript_include_tag 'application'
            = csrf_meta_tags 
            

            【讨论】:

            • 对我来说,解决问题的是= csrf_meta_tags这一行。
            【解决方案10】:

            我必须以与我的 application.rb 不同的方式处理此问题:

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

            并且仍然失败。原来我需要在 /environment/development、test 和 production.rb 中设置config.serve_static_assets = trueThis link 帮助我解决了这个问题。

            【讨论】:

              【解决方案11】:

              你还得查,resources :usersdevise_for :users下面是不是链接方法删除

              link_to "Logout", destroy_user_session_path, method: :delete
              

              如果两者都正确,您的注销按钮应该可以工作

              【讨论】:

                【解决方案12】:

                如果您的 Rails 应用程序中还有多个 jquery 源,则需要使用 Gemfile 中指定的默认源

                确保您的 Gemfile 中有这个

                gem 'jquery-rails'
                

                并且在您的资产中,您没有任何其他 JQuery 源文件。

                在我的情况下,我有第二个 JQuery 文件,而不是 Gemfile 中声明的默认文件,因此它导致了冲突。

                如果您以前有这些源,请务必再次预编译资源(如果您以前这样做过)

                【讨论】:

                • 好收获!这是我的问题
                【解决方案13】:

                我已经尝试了这里提到的所有解决方案,但这个问题的真正解决方案如下:

                <%= link_to "Sign Out", destroy_user_session_path, 'data-turbo-method': :delete%>
                

                如果它不只是刷新或重新启动服务器,它就可以工作。

                【讨论】:

                  【解决方案14】:

                  我同意使用 http DELETE 方法更安静,我喜欢创建一个简单的端点来使用 GET 方法销毁用户会话。

                  通过将其添加到 config/routes.rb

                  devise_scope :user do
                    get '/logout',  :to => 'sessions#destroy'
                  end
                  

                  【讨论】:

                    【解决方案15】:

                    如果您在生产中发现此问题并且正在使用资产管道,您通常需要:

                    rake assets:clobber 以清除您的公共资产。然后 rake assets:precompile 在提交和推送您的代码之前(除非您的推送也预编译,也就是 Heroku)。

                    【讨论】:

                      【解决方案16】:

                      原因可能是连接顺序错误bootstrap-sprockets

                      正确的顺序:

                      // app/assets/javascripts/application.js
                      
                      ...
                      
                      //= require jquery
                      //= require jquery_ujs
                      //= require turbolinks
                      //= require bootstrap-sprockets
                      //= require_tree .
                      

                      【讨论】:

                        【解决方案17】:

                        正如上面Tombart 所提到的,我的答案是将rails-ujs 调用放回我的application.js 文件中。

                        //= require rails-ujs
                        //= require turbolinks
                        

                        我最初删除了它们是为了阻止错误让我在页脚中的脚本被重新评估。我的解决方法是在页脚中使用我想要的资源创建一个 footer.js 编译文件。

                        //= require jquery-3.2.1.min
                        //= require jquery-ui-1.12.1.min
                        //= require materialize
                        //= require init
                        

                        然后在我的 /initializers/assets.rb 文件中添加一个预编译

                        Rails.application.config.assets.precompile += %w( footer.js )
                        

                        然后你可以在你的 layout/application.html.erb 文件中调用下面的内容。

                        <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
                        <%= javascript_include_tag 'footer' %>
                        

                        我将应用程序行保留在我的页眉中,并在我的正文标签末尾添加了我的新“页脚”调用。

                        【讨论】:

                          【解决方案18】:

                          1) 我觉得你可能需要在 gem 下安装,使用 method: :delete 的请求将起作用,否则它可能会像 get 一样进行

                          https://github.com/rails/jquery-rails

                          2) 在 application.js 中添加以下两行

                          //= require jquery
                          //= require jquery_ujs
                          

                          【讨论】:

                            【解决方案19】:
                            Stop the server
                            
                            yarn add  "@rails/ujs"
                            yarn add turbolinks
                            yarn add @rails/activestorage
                            
                            My application.js
                            
                            import Rails from "@rails/ujs"
                            import Turbolinks from "turbolinks"
                            import * as ActiveStorage from "@rails/activestorage"
                            import "channels"
                            
                            Rails.start()
                            Turbolinks.start()
                            ActiveStorage.start()
                            
                            Start the server
                            

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 2020-04-04
                              • 2012-09-27
                              • 1970-01-01
                              • 2013-08-02
                              • 1970-01-01
                              • 2013-05-25
                              • 2018-10-23
                              • 1970-01-01
                              相关资源
                              最近更新 更多