This is an old question, but still rears its ugly head. Here's a different, possibly more appropriate workaround which worked for me.
First, as others describe, the bug happens when using audited (formerly acts_as_audited) with devise (and potentially other authentication gems), and then when you are auditing any of the column Devise uses on your User model (last_sign_in_at, last_sign_in_ip, etc).
- Devise tries to authenticate the user (using its authenticate_user! before_filter).
- Devise tries to update/save the user's sign in info (last_sign_in_at, ip, etc) for posterity
- As part of that save, Audited then tries to create an audit for that change.
- Audited tries to set the User for that Audit, to indicate who made the change. How does it do that?
- Audited calls current_user, a Devise method. Devise isn't yet done with its authenticate method from step 1 - Audited stepped in and is doing its thing. So,
- The current_user method repeats step #1 (the authenticate_user! method), creating an infinite loop
- Your application errors with Stack Level Too Deep
@DGM's workaround simply tells Audited to not audit this change, which might work for you. However, in my application, I need to audit that change.
Audited allows you to specify a different method to use for current_user.
In application controller, add your new method, referring to the current_user instance variable.
def my_cool_method
@current_user
end
And then, in config/initializers/audited.rb, tell Audited to use your new method:
Audited.current_user_method = :my_cool_method
With this change, Audited will still audit the change, but it will not try to set the audit's user (the person who made the change) - that will be nil.
Another advantage of this change over the alternate solution by DGM is that we aren't overriding Devise's current_user method, which is similar to monkey patching in that it could cause unintended consequences later.