如何用Devise“软删除”用户
我目前在Rails项目中使用Devise进行用户注册/authentication。 当用户想要取消他们的帐户时,用户对象被销毁,这使我的应用程序处于不希望的状态。
实施“软删除”最简单的方法是什么,即只删除个人数据并将用户标记为已删除? 我仍然想保留所有的logging协会。
我假设我将不得不首先为用户引入一个新的“删除”列。 但是,我坚持用户的configuration文件视图中的这个默认代码:
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete %>.</p>
我在哪里可以find:delete
方法? 我应该如何覆盖默认的devise方法?
我可以build议覆盖你的用户模型的destroy
方法,只是做update_attribute(:deleted_at, Time.current)
(而不是实际销毁),但是这种偏离标准的API可能在将来变得繁重,所以这里是如何修改控制器。
Devise有一大堆默认的控制器。 定制它们的最好方法是创build自己的控制器,inheritance相应的devise控制器。 在这种情况下,我们正在讨论Devise::RegistrationsController
– 这很容易通过查看源代码来识别。 所以创build一个新的控制器。
class RegistrationsController < Devise::RegistrationsController end
现在我们有我们自己的控制器完全inheritance所有devise提供的逻辑。 下一步是告诉devise使用它,而不是默认的。 在你的路线你有devise_for
线。 应该更改为包含注册控制器。
devise_for :users, :controllers => { :registrations => 'registrations' }
这看起来很奇怪,但这是有道理的,因为默认情况下是“devise/注册”,而不是简单的“注册”。
下一步是重写注册控制器中的destroy
操作。 当你使用registration_path(:user), :method => :delete
– 这就是它连接的地方。 destroy
注册destroy
行为。
目前devise如下。
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
现在你应该一切设置。 使用范围来过滤已删除的用户。
添加到hakunin的答案 :
要防止“软删除”用户login,请覆盖active_for_authentication?
在您的User
模型上:
def active_for_authentication? super && !deleted_at end
您可以使用acts_as_paranoid作为您的用户模型,它设置deleted_at而不是删除对象。
在Devise wiki页面的Soft Delete a Devise User Account上可以find完整的教程。
概要:
1.添加“deleted_at”DATETIME列
2.覆盖用户/注册#在您的路线销毁
3.覆盖用户/注册#在注册控制器中销毁
4.使用soft_delete更新用户模型并检查用户是否处于活动状态
5.添加自定义删除消息