我目前在Rails项目中使用Devise进行用户注册/身份验证。当用户想要取消他们的帐户时,用户对象将被销毁,这会使我的应用程序处于不受欢迎的状态。
实施“软删除”的最简单方法是什么,即仅删除个人数据并将用户标记为已删除?我仍然希望保留所有记录协会。
我假设我必须首先为用户引入一个新的“已删除”列。但后来我在用户的个人资料视图中遇到了这个默认代码:
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete %>.</p>
我在哪里可以找到:delete
方法?我该如何覆盖默认的Devise方法?
答案 0 :(得分:103)
我可以建议在用户模型上覆盖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
现在你应该全力以赴。使用范围过滤掉已删除的用户。
答案 1 :(得分:89)
添加到hakunin's answer:
防止&#34;软删除&#34;用户登录后,覆盖active_for_authentication?
型号上的User
:
def active_for_authentication?
super && !deleted_at
end
答案 2 :(得分:10)
您可以将acts_as_paranoid用于您的用户模型,该模型设置了deleted_at而不是删除对象。
答案 3 :(得分:6)
可以在Devise wiki页面的Soft Delete a Devise User Account找到完整的教程。
要点:
1.添加“deleted_at”DATETIME列
2.覆盖您的路线中的用户/注册#dure
3.覆盖注册控制器中的用户/注册#troy
4.使用soft_delete&amp;更新用户模型。检查用户是否在认证上处于活动状态
5.添加自定义删除消息