deviseの削除機能を実装しようとしたところ理論削除と物理削除があるとのことでした。
論理削除とは
簡単に言うと「データ自体は残っているけど、扱いとしては削除済みにすること」です。
実際にデータを削除せずに、削除されたと見なすフラッグと呼ばれるカラムを設定することでユーザーには削除されてるかのように振る舞うことができることをさします。
データを復元できるメリットもあります。
これにより登録されたデータは残るので、その後の分析などにも役立ちそうです。
物理削除とは
完全にデータベースから削除することです。
データを復元したり、参照することもできません。
実装してみる
- datetime型のdeleted_atカラムを追加
- routingのusers/registrations#destroyをオーバーライド
- registrations controllerのusers/registrations#destroyをオーバーライド
- 論理削除でユーザーモデルを更新し。認証でユーザーがアクティブかどうかを確認する
- delete時のカスタムメッセージを追加
###1. datetime型のdeleted_atカラムを追加
以下をターミナルで実行
rails g migration AddDeletedAtColumnToUsers deleted_at:datetime
rake db:migrate
###2. routingのusers/registrations#destroyをオーバーライド
# devise_for :usersの部分を下記のように修正
devise_for :users, controllers: { registrations: 'users/registrations' }
###3. registrations controllerのusers/registrations#destroyをオーバーライド
app/controllers/users/registrations_controller.rb
を作成する。
ここでDevise registrations controllerを継承し、destroyをオーバーライドする。
# app/controllers/users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
# DELETE /resource
def destroy
resource.soft_delete
Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
set_flash_message :notice, :destroyed
yield resource if block_given?
redirect_to root_path
end
end
###4. 論理削除でユーザーモデルを更新し。認証でユーザーがアクティブかどうかを確認する
# app/models/user.rb
# 物理削除の代わりにユーザーの`deleted_at`をタイムスタンプで更新
def soft_delete
update_attribute(:deleted_at, Time.current)
end
# ユーザーのアカウントが有効であることを確認
def active_for_authentication?
super && !deleted_at
end
# 削除したユーザーにカスタムメッセージを追加します
def inactive_message
!deleted_at ? super : :deleted_account
end
###5. delete時のカスタムメッセージを追加
# config/locales/ja.yml
ja:
devise:
failure:
deleted_account: "このアカウントは既に削除されています。"
参考:
How to: Soft delete a user when user deletes account
【翻訳】deviseで論理削除を実装する方法
論理削除 (logical delete)