デフォルトだとアカウント削除ボタンは登録情報変更ページにありますが、目的が違う機能が同じ画面にあるのは危ない(間違う可能性がある)ので、確認画面を作成しました。
(この後、即時削除ではなく、削除予約を実装する布石でもあります。)

確認ページのルート追加

先ずはSpec

spec/routing/users/registrations_routing_spec.rb に追加

    it 'routes to #delete' do
      expect(get: '/users/delete').to route_to('users/registrations#delete')
    end

確認

$ rspec spec/routing/users/registrations_routing_spec.rb
Failures:

  1) Users::RegistrationsController routing routes to #delete
     Failure/Error: expect(get: '/users/delete').to route_to('users/registrations#delete')
       No route matches "/users/delete"

7 examples, 1 failure

Spec通るように実装

config/routes.rb に追加

  devise_scope :user do
    get 'users/delete', to: 'users/registrations#delete'
  end

ポイント:devise_forで指定している:users(複数形)ではなく、devise_scopeでは:user(単数形)で指定

app/controllers/users/registrations_controller.rb に追加

  # GET /users/delete アカウント削除
  # def delete
  # end

確認

$ rspec spec/routing/users/registrations_routing_spec.rb
7 examples, 0 failures

確認ページのビュー作成と導線変更

app/views/users/registrations/delete.html.erb を作成

<h2>アカウント削除</h2>

<p><%= button_to "削除確認", registration_path(resource_name), data: { confirm: "アカウント削除:本当に削除しますか?(ログイン出来なくなります)" }, method: :delete %></p>

<ul>
  <li><%= link_to "登録情報変更", edit_user_registration_path %></li>
</ul>

app/views/users/registrations/edit.html.erb を変更
修正前

<hr/>

<h2>アカウント削除</h2>

<p><%= button_to "削除確認", registration_path(resource_name), data: { confirm: "アカウント削除:本当に削除しますか?(ログイン出来なくなります)" }, method: :delete %></p>


修正後

<ul>
  <li><%= link_to "アカウント削除", users_delete_path %></li>
</ul>

確認

$ rails s
-> http://localhost:3000/users/edit

未ログインの場合はログインにリダイレクト

未ログインで下記にアクセスすると表示できてしまう。
ログインにリダイレクトして、ログイン後、ここに戻るようにしたい。
http://localhost:3000/users/delete

先ずはSpec

spec/requests/users/registrations_spec.rb に追加

  let!(:user) { FactoryBot.create(:user) }
  shared_context 'ログイン処理' do
    before { sign_in user }
  end

  # GET /users/delete アカウント削除
  describe 'GET /users/delete' do
    context '未ログイン' do
      it 'ログインにリダイレクト' do
        get users_delete_path
        expect(response).to redirect_to(new_user_session_path)
      end
    end
    context 'ログイン中' do
      include_context 'ログイン処理'
      it 'renders a successful response' do
        get users_delete_path
        expect(response).to be_successful
      end
    end
  end

確認

$ rspec spec/requests/users/registrations_spec.rb
Failures:

  1) Users::Registrations GET /users/delete 未ログイン ログインにリダイレクト
     Failure/Error: expect(response).to redirect_to(new_user_session_path)
       Expected response to be a <3XX: redirect>, but was a <200: OK>
     # ./spec/requests/users/registrations_spec.rb:25:in `block (4 levels) in '

3 examples, 1 failure

Spec通るように実装

app/controllers/users/registrations_controller.rb に追加

  prepend_before_action :authenticate_scope!, only: [:edit, :update, :destroy, :delete]

ボツ案1 -> スマートじゃない

  def delete
    unless user_signed_in?
      store_location_for(:user, request.fullpath)
      return redirect_to new_user_session_path
    end
  end

ボツ案2 -> ArgumentError in Users::Registrations#edit

  prepend_before_action :authenticate_scope!, only: [:delete]

参考:.rvm/gems/ruby-2.6.3/gems/devise-4.7.2/app/controllers/devise/registrations_controller.rb

  prepend_before_action :authenticate_scope!, only: [:edit, :update, :destroy]

確認

$ rspec spec/requests/users/registrations_spec.rb
3 examples, 0 failures
$ rails s
-> http://localhost:3000/users/delete

【参考】ここまでのコミット内容
https://dev.azure.com/nightonly/rails-app-origin/_git/rails-app-origin/commit/585daf9639094511b6c9e7a70a263e180ed28d4c

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です