2
0

More than 3 years have passed since last update.

redirect_back(fallback_location: root_url)で常にエラーが発生していた話

Posted at

前提

rspecでmod操作をチェックすることができるようになったので、確認ダイアログが表示される操作の統合テストを追加した。(data: { confirm: "削除してよろしいですか?" }の部分)

しかしその際に、エラーが発生したので、その修正に軌跡をここに記しておくこととする。

ちなみに、RSpecで確認ダイアログを操作するコードは以下を参考にしました。ありがとうございました!!

結論

遷移の前のページが削除される操作の場合、redirect_backという指示は適切ではない。

エラーの原因とその修正

テストした箇所と、エラーが発生していた部分、その修正。

app/views/works/show.html.erb
:
<% if current_user?(@work.user) %>
    <div class="work--settings">
      <span class="delete_btn field__negative">
        <%= link_to "削除する", work_path(@work), method: :delete, data: { confirm: "削除してよろしいですか?" } %>
      </span>
    </div>
<% end %>
:
app/controllers/works_controller.rb
 class WorksController < ApplicationController
    :
   def destroy
     @work.destroy
     flash[:success] = "削除しました。"
-    redirect_back(fallback_location: root_url)
+    redirect_to root_url
   end
    :
spec/system/works/create_work_spec.rb
require "rails_helper"

RSpec.describe "Create or delete work", type: :system, js: true do
  let(:user) { create(:user) }
  let(:work) { create(:work, user_id: user.id) }

  it "delete work" do
    sign_in user
    visit work_path work
    within(".work--settings") do
      expect(page).to have_selector "span.delete_btn"
      page.accept_confirm do
        click_link "削除する"
      end
    end
  end
end

エラーコード
Create or delete work
  delete work (FAILED - 1)

Failures:

  1) Create or delete work delete work
     Failure/Error:
       @work = Work.includes(
         [
           :user,
           comments: :user,
           image_attachment: :blob,
           illustrations: [photo_attachment: :blob],
         ]
       ).find(params[:id])

     ActiveRecord::RecordNotFound:
       Couldn't find Work with 'id'=3313
     # ./app/controllers/works_controller.rb:15:in `show'

     :

     # ------------------
     # --- Caused by: ---
     # Capybara::CapybaraError:
     #   Your application server raised an error - It has been raised in your test code because Capybara.raise_server_errors == true
     #   /usr/local/bundle/gems/capybara-3.35.3/lib/capybara/session.rb:160:in `raise_server_error!'

Finished in 5.17 seconds (files took 3.93 seconds to load)
1 example, 1 failure

原因

原因は削除操作にて、redirect_back(fallback_location: root_url)という、redirect_backの操作を行っていた事に由来します。

app/controllers/works_controller.rb
 class WorksController < ApplicationController
    :
   def destroy
     @work.destroy
     flash[:success] = "削除しました。"
-    redirect_back(fallback_location: root_url)
+    redirect_to root_url
   end
    :

fallback_locationというオプションは遷移前のページのURL取得する操作でした。しかし、遷移の前のページ(今回でいうworks/show.html.erb)が削除される操作の場合は、そもそもredirect_backという指示は適切なはずがなく、エラーが発生していました。
ちなみにこの修正は、以下の記事を参考にしました。ありがとうございました!

つまり、自分のアプリケーションにはエラーが発生するコードが、常に内在していた、と言うことになります。情けない、、
改めてテストの重要性に気付かされました。

今回の記事は以上です、最後まで読んでいただきありがとうございました!!

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0