ruby 如何使用Devise“软删除”用户

omqzjyyz  于 2022-12-22  发布在  Ruby
关注(0)|答案(5)|浏览(182)

我目前在Rails项目中使用Devise进行用户注册/身份验证,当用户想要取消他们的帐户时,用户对象会被销毁,这会使我的应用程序处于不希望的状态。
实现“软删除”(即只删除个人数据并将用户标记为已删除)的最简单方法是什么?我仍然希望保留所有记录关联。
我想我必须首先为用户引入一个新的“已删除”列,但是我在用户的个人资料视图中使用了以下默认代码:

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

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

lnxxn5zx

lnxxn5zx1#

我可以建议在用户模型上覆盖destroy方法,简单地执行update_attribute(:deleted_at, Time.current)(而不是实际销毁),但这种与标准API的偏离在未来可能会成为负担,因此下面介绍如何修改控制器。
Devise有一堆默认的控制器。定制它们的最好方法是创建你自己的控制器,继承相应的devise控制器。在这个例子中,我们讨论的是Devise::RegistrationsController-通过查看源代码很容易识别。所以创建一个新的控制器。

class RegistrationsController < Devise::RegistrationsController
end

现在我们有了自己的控制器,完全继承了device提供的所有逻辑。下一步是告诉device使用它来代替默认的。在你的路由中你有devise_for行。它应该被修改为包括registrations controller。

devise_for :users, :controllers => { :registrations => 'registrations' }

这看起来很奇怪,但这是有道理的,因为默认情况下,它是“设计/注册”,而不仅仅是“注册”。
下一步是覆盖注册控制器中的destroy操作。当你使用registration_path(:user), :method => :delete时-这是它链接的地方。到注册控制器的destroy操作。
当前device执行以下操作。

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

现在你应该都设置好了。使用作用域来过滤掉已删除的用户。

dpiehjr4

dpiehjr42#

对哈库宁的回答补充道:
要阻止“软删除”用户登录,请覆盖User型号上的active_for_authentication?

def active_for_authentication?
  super && !deleted_at
end
k5hmc34c

k5hmc34c3#

您可以将acts_as_paranoid用于用户模型,它设置deleted_at而不是删除对象。

ldfqzlk8

ldfqzlk84#

完整的教程可以在Devise wiki页面的Soft Delete a Devise User Account上找到。
总结:
1.添加"deleted_at"日期时间列
2.覆盖路由中的用户/注册#destroy
3.覆盖注册控制器中的用户/注册#destroy
4.使用soft_delete更新用户模型,并检查用户在身份验证时是否处于活动状态
5.添加自定义删除消息

t9eec4r0

t9eec4r05#

def devise_current_user
   @current_user ||= warden.authenticate(scope: :user)
  end

  def current_user
    if params[:user_id].blank?
      devise_current_user
    else
      User.find(params[:user_id])
    end
  end

相关问题