2

我正在使用设计作为 rails 3.2 应用程序的身份验证。我的用户模型称为用户,我一直在尝试实现软删除。我正在尝试通过使用acts_as_paranoid 来做到这一点,它会自动为您完成工作。事情按预期工作(其他人无法再看到“已删除”用户),除了我希望停用的用户仍然能够登录并看到“停用”屏幕,并让他们有机会重新激活他们的帐户。

问题是 Devise(Warden?)不再能够找到已删除的用户。如果您使用范围“with_deleted”,Acts_as_paranoid 允许您访问软删除记录。因此,我可以通过以下方式获得其中的一部分:

def self.find_first_by_auth_conditions(warden_conditions)
  conditions = warden_conditions.dup
  where(conditions).with_deleted.first
end

我把它放到我的用户模型中,所以现在当我输入登录信息时,我会得到我已经成功登录的闪存消息,它会触摸用户模型中的“updated_at”列并增加sign_in_count 等。但是,从经过身份验证的方法返回 false 并且 current_user 辅助方法返回 nil 的意义上,它并没有真正进行身份验证。那么让这些工作的最佳策略是什么?我可以以某种方式覆盖 current_user 方法,以便它使用 with_deleted 范围查询 User 模型吗?我是否必须对warden 做一些事情,例如像使用 find_first_by_auth_conditions 方法那样添加条件?我无法弄清楚如何做到这一点。任何帮助表示赞赏!

另外,在我让它工作之后,我想自动将所有软删除的用户发送到一个“停用”页面,他们唯一的选择是永久删除或重新激活。有没有办法通过“authenticated :user do {} end”路由来做到这一点,还是我必须在 application_controller 中放置一个 before_filter 并在每个请求时检查用户?

4

2 回答 2

0

我可以回答你的最后一个问题,关于路由到“停用页面”。您可以使用 lambda 来隔离不同类型的用户,如下所示:

authenticated :user, lambda {|u| u.deactivated? } do
  root :to => 'application#deactivated'
end
authenticated :user, lambda {|u| u.active? } do
  root :to => 'application#active'
end
于 2013-04-16T15:39:02.827 回答
0

感谢 Devise 组的提示,事实证明我需要覆盖 serialize_from_session 方法,该方法位于可验证模块内,如下所示:

def serialize_from_session(key, salt)
  record = to_adapter.get(key)
  record if record && record.authenticatable_salt == salt
end

我一直在尝试使用初始化程序覆盖模块但没有成功(我试图覆盖现有策略,并尝试为warden编写一个新策略);但我不断收到奇怪的名称错误。我还没有弄清楚。但是,根据提示,我继续并覆盖了我的用户模型中的方法。由于我没有预见到使用其他资源,所以我不介意像这样编辑它。代码只是:

def self.serialize_from_session(key, salt)
  record = with_deleted.find(key).first
  record if record && record.authenticatable_salt == salt
end

这完全跳过了 to_adapter.get 方法(对于任何感兴趣的人,它在 orm_adapter 中,而不是设计;这花了我一段时间才找到,因为我认为我需要覆盖它)。这可能不是最干净的方法,但对我来说效果很好。即使我确实有不同的资源,这也应该只覆盖用户资源,所以我认为否则一切都会正常工作。

如果出现问题,我会在此处添加。如果没有,希望这能以某种方式帮助某人。当然,我花了足够长的时间才能深入了解!

于 2013-04-18T01:36:34.957 回答