Rails - Devise和acts_as_audited

时间:2010-08-03 16:27:06

标签: ruby-on-rails devise acts-as-audited

嘿,我想一起使用Devise和acts_as_audited但是当我尝试使用它们链接它们时 -

class ApplicationController < ActionController::Base
 audit Candidate
 protected

 def current_user
   @user = User.find(user_session)    
 end

我收到此错误。

stack level too deep

我需要采用不同的方式吗?

由于

4 个答案:

答案 0 :(得分:4)

这是一个老问题,但仍然是丑陋的头脑。这是一个不同的,可能更合适的解决方法,对我有用。

首先,正如其他人所描述的那样,当使用audited(以前的acts_as_audited)和设计(以及可能的其他身份验证宝石)时,会发生错误,然后当您审计用户模型上的任何列Devise使用时(last_sign_in_at,last_sign_in_ip,等)。

  1. Devise尝试对用户进行身份验证(使用其authenticate_user!before_filter)。
  2. Devise尝试更新/保存用户的登录信息(last_sign_in_at,ip等)以供后代使用
  3. 作为该保存的一部分,Audited会尝试为该更改创建审核。
  4. 审核尝试为该审核设置用户,以指明进行更改的用户。它是如何做到的?
  5. 审计调用current_user,一个Devise方法。从步骤1开始,它的验证方法尚未完成 - 审计已介入并正在执行其操作。所以,
  6. current_user方法重复步骤#1(authenticate_user!方法),创建无限循环
  7. 您的应用程序错误,堆栈级别太深
  8. @ DGM的解决方法只是告诉Audited不审核此更改,这可能对您有用。但是,在我的应用程序中,我需要审核该更改。

    Audited允许您指定用于current_user的其他方法。

    在应用程序控制器中,添加新方法,参考current_user 实例变量

    def my_cool_method
        @current_user
    end
    

    然后,在config / initializers / audited.rb中,告诉Audited使用您的新方法:

    Audited.current_user_method = :my_cool_method
    

    通过此更改,Audited仍会审核更改,但不会尝试设置审核用户(进行更改的人) - 这将是零。

    这种对DGM替代解决方案的改变的另一个好处是我们没有覆盖Devise的current_user方法,这类似于猴子修补,因为它可能会在以后造成意外后果。

答案 1 :(得分:1)

只是关闭它。

堆栈级别太深是因为devise内置了对current_user变量的审计。

因此,每次访问变量时都会导致无限循环。

答案 2 :(得分:1)

进一步解释 - acts_as_audited在检查要忽略的内容之前调用current_user,如果current_user触发表更改,则再次调用审计,poof。无限循环。

与authlogic相同的问题的解决方法是在设置会话时禁用审核:

def current_user
  return @current_user if defined?(@current_user)
  User.without_auditing do
    @current_user = current_user_session && current_user_session.user
  end
  @current_user
end

然而,我还是打了一些我不想打的回调。这是authlogic的问题,而不是act_as_audited的问题。

最后,我希望设计或authlogic完成的审计以绕过验证,回调和时间戳的方式进行审计。

答案 3 :(得分:0)

仅Authlogic就会发生同样的事情。解决方案是使用以下字段添加:except参数(参见下文)。也许类似的东西也适用于Devise。

  

#明确定义否则“Stack   等级太深了“

     

acts_as_audited   :except =&gt; [:persistence_token,
  :perishable_token,:login_count,
  :failed_login_count,
  :last_request_at,:current_login_at,   :last_login_at,:current_login_ip,
  :last_login_ip]