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