【问题标题】:How to skip a before_filter for Devise's SessionsController?如何跳过设计的 SessionsController 的 before_filter?
【发布时间】:2011-06-02 02:03:35
【问题描述】:

我的ApplicationController 中有一个before_filter;也就是说,对于我项目中的每个控制器。

我如何 skip_before_filter 为 Devise 的 SessionsController 创建操作?

【问题讨论】:

    标签: ruby-on-rails devise before-filter


    【解决方案1】:

    这是我同事刚刚向我展示的一种方法:

    # In config/application.rb
    module YourAppNameHere
      class Application < Rails::Application
      # Whatever else is already here...
    
        # The part to add
        config.to_prepare do
          Devise::SessionsController.skip_before_filter :your_before_filter_here
        end
      end
    end
    

    【讨论】:

    • 这对我来说非常有效,我根本无法得到公认的答案。所以 +1 - 谢谢!
    • 我对接受的答案也有问题。我试过了,它奏效了,但我的应用程序明显变慢了(从一个页面移动到另一个页面可能增加了大约 1 秒)。
    • @John - 我不确定为什么 to_prepare 块对你来说会这么慢,但仅供参考,根据 Rails 指南,这样的块“将在开发中的每个请求上运行,但是在生产和测试中只有一次(在启动期间)。”
    • 我使用的是devise_token_auth gem,我只需要将Devise::SessionsController 替换为DeviseTokenAuth::SessionsController,效果非常好!
    • @BKSpureon 你可以使用Devise::SessionsController.skip_before_filter :check_toc, only: [:new]
    【解决方案2】:

    我最近在我的application_controller 中遇到了这个过滤器问题,我使用skip_before_filter 解决了这个问题

    skip_before_filter :check_subdomain!, if: :devise_controller?
    

    【讨论】:

    • skip_before_action :check_subdomain!, if: :devise_controller?
    【解决方案3】:

    我们做了这样的事情:

    首先,创建你自己的会话控制器,确保正确继承:

    class SessionsController < Devise::SessionsController
      skip_before_filter :foobar
    

    然后修复路线

    devise_for :users,
      :controllers => {
        :sessions => "sessions"
      }
    

    或者,您可以对 Devise 的会话控制器进行猴子补丁。

    【讨论】:

    • 这听起来不错,但我无法让它工作:/
    • 我发现这个解决方案比更受欢迎的解决方案“更干净”。它将控制器逻辑保存在控制器中。
    【解决方案4】:

    这是 lib/devise_sessions_controller_decorator.rb 中的另一种方式:

    module DeviseSessionsControllerDecorator
      extend ActiveSupport::Concern
    
      included do
        skip_before_filter :your_filter_name
      end
    end
    
    Devise::SessionsController.send(:include, DeviseSessionsControllerDecorator)
    

    由于类在开发模式下没有缓存,你可能需要在 config/environments/development.rb 中添加类似这样的内容:

    config.to_prepare do
      Devise::SessionsController.send(:include, DeviseSessionsControllerDecorator)
    end
    

    【讨论】:

      【解决方案5】:

      在我的同事向我展示我在其他答案中发布的方式之前,我已经这样做了。如果您认为它更简单,我会发布此内容。

      class ApplicationController < ActionController::Base
        # ...
        before_filter :do_something
      
        def do_something
          unless params[:controller] == 'devise/sessions'
            # ...
          end
        end
      end
      

      【讨论】:

        【解决方案6】:

        您可以简单地检查您的过滤方法是否是设计控制器。

          if params[:controller] != 'devise/sessions'
        

        【讨论】:

          【解决方案7】:

          新答案

          如何将 before_filter 包装在 params[:controller] 的除非块过滤中

          def some_before_action
            unless params[:controller] == "sessions_controller_for_devise_name"
                ... #=> do the stuff here
            end 
          end
          

          旧答案

          只授权哪些动作应该使用前置过滤器

          before_filter :action, :only => ...
          

          并授权你的其他人。

          found this here

          【讨论】:

          • 我知道,但是为了像这样工作,你需要把它放在会话控制器中。那是设计 gem 的控制器。这绝对不是一个好主意:/
          • 你能用 :only => 过滤你想要的吗?
          • 编辑了答案,这可能有效吗?如果在应用程序控制器中可用,则使用 params[:controller]
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-01-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-12-17
          • 1970-01-01
          • 2021-07-24
          相关资源
          最近更新 更多