Rails/Devise: execute action after automatic login

2019-09-02 04:57发布

问题:

EDIT: I use Devise 3.4.1, and after_remembered isn't available. Either apply this small patch or use a newer version released after 2014/11/09.

Alright, so I am rather new to the Rails environment, and I feel I am missing something.

I wish to execute a particular action after login, be it after login from a form or automatic login.

I found out that after_sign_in_path_for is executed after a "regular" login. I already use it in my Application controller.

class ApplicationController < ActionController::Base

[…]

def after_sign_in_path_for(resource)
    myAction
end

However, it seems that this method isn't called when a user is logged in through the Devise Remember option.

I found out that after_remembered is executed after a user is automatically logged in, however I don't understand how to use it. I don't want to modify the Devise gem just to add my action to the method, and the following doesn't seem to work:

class ApplicationController < ActionController::Base

[…]

def after_remembered()
    myAction
end

I am at a loss here. Either I don't understand how to use after_remembered, or I look at it the wrong way and there is another solution for that (should it cover either both cases or only the case with "remember me" automatic login, is fine for me). Does anyone have any idea to make it work?

PS: I am working on an app I haven't developed myself. If you feel you need more code in order to answer, tell me and I will edit my post.

回答1:

It's part of the Rememberable module so it belongs in your model... assuming your resource is User the way you would use it is...

class User < ActiveRecord::Base

  devise :rememberable

  def after_remembered
    # (your code here)
  end

end

I'm not sure if Devise offers a controller-specific method but if not you could throw one togeter... create an attribute in your User model called, say, signed_in_via_remembered

class User < ActiveRecord::Base

  devise :rememberable

  def after_remembered
    update_attribute(:signed_in_via_remember, true)
  end

end

then in your application_controller.rb

class ApplicationController < ActionController::Base

  before_action :handle_sign_in_via_rememberable

  def handle_sign_in_via_rememberable
    if current_user and current_user.signed_in_via_remember?
      current_user.update_attribute(:signed_in_via_remember, false)    
      after_sign_in_path_for(User)
    end
  end

  def after_sign_in_path_for(resource)
    myAction
  end

end

Someone may have a neater solution.