現在、Railsプロジェクトでのユーザー登録/認証にDeviseを使用しています。ユーザーがアカウントをキャンセルしたい場合、ユーザーオブジェクトは破棄され、アプリケーションが望ましくない状態になります。
「ソフト削除」を実装する最も簡単な方法は何ですか?つまり、個人データのみを削除し、ユーザーを削除済みとしてマークするだけですか?私はまだすべてのレコードの関連付けを保持したいです。
まず、ユーザーに新しい「削除済み」列を導入する必要があると思います。しかし、その後、ユーザーのプロファイルビューでこのデフォルトコードを使用します。
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete %>.</p>
:delete
メソッドはどこにありますか?デフォルトのDeviseメソッドをどのように上書きする必要がありますか?
Userモデルでdestroy
メソッドをオーバーライドして、実際に破壊する代わりにupdate_attribute(:deleted_at, Time.current)
を実行することをお勧めしますが、標準APIからのこの逸脱は将来負担になる可能性があるため、ここで変更する方法を示しますコントローラー。
Deviseには、すぐに使えるデフォルトのコントローラーがたくさんあります。それらをカスタマイズする最良の方法は、対応するdeviseコントローラーを継承する独自のコントローラーを作成することです。この場合、私たちは_Devise::RegistrationsController
_について話します—これはソースを見ることで簡単に認識されます。そのため、新しいコントローラーを作成します。
_class RegistrationsController < Devise::RegistrationsController
end
_
これで、デバイスが提供するすべてのロジックを完全に継承する独自のコントローラーができました。次のステップでは、デバイスにデフォルトの代わりにそれを使用するように指示します。ルートには_devise_for
_行があります。登録コントローラーを含めるように変更する必要があります。
_devise_for :users, :controllers => { :registrations => 'registrations' }
_
これは奇妙に思えますが、デフォルトでは単に「登録」ではなく「開発/登録」であるため、理にかなっています。
次のステップは、登録コントローラーのdestroy
アクションをオーバーライドすることです。 registration_path(:user), :method => :delete
を使用すると、そこにリンクします。登録コントローラーの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's answer に追加する:
「ソフト削除」されたユーザーがサインインできないようにするには、active_for_authentication?
User
モデル:
def active_for_authentication?
super && !deleted_at
end
Userモデルには acts_as_paranoid を使用できます。これは、オブジェクトを削除する代わりにdeleted_atを設定します。
完全なチュートリアルは、Devise Wikiページの Soft Delete a Devise User Account にあります。
概要:
1。 「deleted_at」DATETIME列を追加します
2。ルートでユーザー/登録を上書きする#destroy
3。登録コントローラーでusers/registrations#destroyをオーバーライドします
4。 soft_deleteを使用してユーザーモデルを更新し、ユーザーが認証でアクティブかどうかを確認します
5。カスタム削除メッセージを追加する