如何用Devise“软删除”用户
我目前在Rails项目中使用Devise进行用户注册/身份验证。当用户想要取消他们的账户时,用户对象被销毁,这使我的应用程序处于不希望的状态。如何用Devise“软删除”用户
什么是实施“软删除”的最简单方法,即只删除个人数据并将用户标记为已删除?我仍然想保留所有的记录关联。
我假设我将不得不首先为用户引入一个新的“已删除”列。但后来我坚持在用户的个人资料查看此默认代码:
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete %>.</p>
我在哪里可以找到:delete
方法?我应该如何覆盖默认的Devise方法?
我可以建议覆盖您的用户模型中的destroy
方法,以简单地执行update_attribute(:deleted_at, Time.current)
(而不是实际销毁),但这种与标准API的偏差可能在未来变得繁重,因此以下是如何修改控制器。
Devise拥有一堆开箱即用的默认控制器。定制它们的最好方法是创建自己的控制器,继承相应的设计控制器。在这种情况下,我们正在谈论Devise::RegistrationsController
- 这很容易通过查看源代码来识别。所以创建一个新的控制器。
class RegistrationsController < Devise::RegistrationsController
end
现在我们有我们自己的控制器完全继承所有设计提供的逻辑。下一步是告诉设计使用它而不是默认的。在你的路线中,你有devise_for
行。应该更改为包含注册控制器。
devise_for :users, :controllers => { :registrations => 'registrations' }
这似乎很奇怪,但它很有意义,因为默认情况下它是'设计/注册',而不仅仅是'注册'。
下一步是重写注册控制器中的destroy
操作。当您使用registration_path(:user), :method => :delete
- 这是它链接的地方。到destroy
注册控制器的行动。
目前设计做到以下几点。
def destroy
resource.destroy
set_flash_message :notice, :destroyed
sign_out_and_redirect(self.resource)
end
我们可以改用此代码。首先让我们给User
模型添加新的方法。
class User < ActiveRecord::Base
def soft_delete
# assuming you have deleted_at column added already
update_attribute(:deleted_at, Time.current)
end
end
# Use this for Devise 2.1.0 and newer versions
class RegistrationsController < Devise::RegistrationsController
def destroy
resource.soft_delete
Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
set_flash_message :notice, :destroyed if is_navigational_format?
respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }
end
end
# Use this for older Devise versions
class RegistrationsController < Devise::RegistrationsController
def destroy
resource.soft_delete
set_flash_message :notice, :destroyed
sign_out_and_redirect(resource)
end
end
现在你应该全部设置。使用范围来过滤已删除的用户。
您可以使用acts_as_paranoid作为您的用户模型,该模型设置deleted_at而不是删除对象。
我以前听过那个。它如何与Devise进行互动?除了安装'acts_as_paranoid'之外,我需要改变什么? – slhck 2011-02-28 10:35:05
@shick ...您应该将'acts_as_paranoid'行添加到您的用户模型(或任何其他需要软删除的模型)。 – rubyprince 2011-02-28 11:05:46
这个宝石有很多的分支/版本,我找不到一个适用于Rails 3.2.x的工具。 – 2012-12-10 14:38:39
添加到hakunin's answer:
为了防止“软删除”用户登录,覆盖active_for_authentication?
您User
型号:
def active_for_authentication?
super && !deleted_at
end
+1从当前会话中删除新删除的用户的正确钩子。 – 2011-11-23 17:45:28
这真的是最好的答案。 [这里是文档](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Authenticatable)。 – 2012-12-10 19:29:40
感谢您的支持,我唯一不喜欢的部分是与未确认帐户共享的消息。看到我的答案如何更改该消息:http://*.com/a/14966003/637094 – Leito 2013-02-19 19:47:58
一个完整的教程可以在Soft Delete a Devise User Account的设计wiki页面上找到。
摘要:
1.添加 “deleted_at” DATETIME列
2.覆盖用户/注册#摧毁你的路由
3.覆盖用户/注册#消灭在注册控制器
4.更新用户带soft_delete的型号&检查用户是否在认证时处于活动状态
5.添加自定义删除消息
删除用户时应该发生什么?他的所有帖子/活动是否应该被删除? – khelll 2011-02-28 10:25:03
我想保留与其他对象的所有关联,但只删除个人数据(名称/电子邮件地址)并禁用登录。 – slhck 2011-02-28 10:34:00