2013-04-04 72 views
1

我正在使用Devise来处理Rails应用程序中的身份验证,并且我正在使用permanent_records来软删除用户。我的用户模型的默认范围是未删除的用户。如果用户删除(停用)他的账户,我希望他能够通过登录重新激活他的账户,类似于Facebook的做法。问题是,由于Devise不知道要查找已删除的用户,因此未找到任何帐户。我想到重写会话#创建方法在Devise身份验证中使用删除的作用域

def create 
    self.resource = warden.authenticate!(auth_options) 
    set_flash_message(:notice, :signed_in) if is_navigational_format? 
    sign_in(resource_name, resource) 
    respond_with resource, :location => after_sign_in_path_for(resource) 
    end 

但因为这是由监狱长处理,看来我的运气。恐怕如果我开始挖得太深,我会开始打破事情。

任何想法?

谢谢!

回答

4

您需要:

  1. 覆盖find_for_authentication在用户模型的方法,让你的模型在这里找到任何用户https://github.com/plataformatec/devise/blob/master/lib/devise/models/authenticatable.rb#L229

  2. 重新定义after_database_authentication方法来删除删除标志https://github.com/plataformatec/devise/blob/master/lib/devise/models/database_authenticatable.rb#L98

我相信这就是全部。无需触摸控制器操作。

+0

真棒!所以,如果我重写find_for_authentication,我该如何告诉它不要使用默认范围?他们的例子是find_first_by_auth_conditions(tainted_conditions,:active => true),但我不想要:deleted => true,我希望删除和未删除的记录,以便我可以应用一些特殊的逻辑删除记录。 – 2013-04-04 22:50:18

+0

更具体地说,如果我可以做一些像user = super || find_first_by_auth_conditions(tainted_conditions,:deleted_at =>“IS NOT NULL”)但当然“IS NOT NULL”不是我可以传递给散列的东西。如何找到deleted_at存在的记录? – 2013-04-04 23:15:15

+1

你可以在这里写自己的发现者(因为你知道你的适配器和字段)'unscoped.where(tainted_conditions).first' – MikDiet 2013-04-04 23:25:19

0

这个作品与偏执宝石:

class << self 
    def find_for_authentication(conditions) 
    User.unscoped do 
     user = super(conditions) 
     user.restore!(recursive: true) if user.deleted? 
     user 
    end 
    end 
end