如何"软删除"用户设计

时间:2011-02-28 10:13:14

标签: ruby-on-rails ruby authentication

我目前在Rails项目中使用Devise进行用户注册/身份验证。当用户想要取消他们的帐户时,用户对象将被销毁,这会使我的应用程序处于不受欢迎的状态。

实施“软删除”的最简单方法是什么,即仅删除个人数据并将用户标记为已删除?我仍然希望保留所有记录协会。

我假设我必须首先为用户引入一个新的“已删除”列。但后来我在用户的个人资料视图中遇到了这个默认代码:

<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete %>.</p>

我在哪里可以找到:delete方法?我该如何覆盖默认的Devise方法?

4 个答案:

答案 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.添加自定义删除消息