From 094e903974910a5b1f215acad01fe62fb38831b7 Mon Sep 17 00:00:00 2001 From: edubraqd Date: Thu, 17 Sep 2026 10:18:58 -0300 Subject: [PATCH] Answer address requests for a person without one with a 404 set_address handed nil to show, update and destroy when the person had no address yet, so each of them raised (nil partial, nil.update, nil.destroy!) and answered 500. Raising RecordNotFound there turns all three into the 404 they should be. Co-Authored-By: Claude Opus 5 --- app/controllers/addresses_controller.rb | 5 +++- test/controllers/addresses_controller_test.rb | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/app/controllers/addresses_controller.rb b/app/controllers/addresses_controller.rb index ddfba73..0b8f86a 100644 --- a/app/controllers/addresses_controller.rb +++ b/app/controllers/addresses_controller.rb @@ -46,8 +46,11 @@ def set_person @person = Person.find(params[:person_id]) end + # A person has at most one address, and may have none yet: show, update and + # destroy on a person without one are a 404, not a nil blowing up in the + # action. def set_address - @address = @person.address + @address = @person.address || raise(ActiveRecord::RecordNotFound.new("Person #{@person.id} has no address", "Address")) end def address_params diff --git a/test/controllers/addresses_controller_test.rb b/test/controllers/addresses_controller_test.rb index 93dfabf..dcd8ca3 100644 --- a/test/controllers/addresses_controller_test.rb +++ b/test/controllers/addresses_controller_test.rb @@ -25,4 +25,28 @@ class AddressesControllerTest < ActionDispatch::IntegrationTest end assert_redirected_to person_url(@person) end + + test "show is a 404 for a person without an address" do + @person.address.destroy + + get person_address_url(@person) + assert_response :not_found + end + + test "update is a 404 for a person without an address" do + @person.address.destroy + + patch person_address_url(@person), params: { address: { city: "Springfield" } } + assert_response :not_found + assert_equal 0, Address.where(person_id: @person.id).count + end + + test "destroy is a 404 for a person without an address" do + @person.address.destroy + + assert_no_difference("Address.count") do + delete person_address_url(@person) + end + assert_response :not_found + end end