我可以建议在您的 User 模型上覆盖 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
现在你应该准备好了。使用范围过滤掉已删除的用户。