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