Fix 500 on Today tab: set @queued_property_ids in create action #75
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/500-queued-property-ids-nil"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
POST /today— adding a property to the work queue crashed because@queued_property_idswas nil in the turbo stream responsecreateaction renders_property_itempartial which calls@queued_property_ids.include?, but onlyindexset that ivar@queued_property_idsafter successful save, before turbo stream rendersChanges
app/controllers/work_queue_items_controller.rb: Add@queued_property_ids = WorkQueueItem.where(work_date: date).pluck(:property_id).to_setin thecreateaction after successful saveTest Plan
Review Checklist
Related Notes
ldraney/landscaping-assistant #74— 500 on POST /todaylandscaping-assistant— project this work belongs toCloses #74
PR #75 Review
DOMAIN REVIEW
Tech stack: Ruby on Rails 8, Turbo Streams, RSpec request specs.
The fix is correct for
create. The root cause is well-identified:_property_item.html.erb(line 11) calls@queued_property_ids.include?(property.id), but onlyindexset that ivar. The one-line addition atapp/controllers/work_queue_items_controller.rb:30queries after save and before turbo stream render -- correct placement and correct query.Same bug exists in
destroyaction (lines 50-59). Thedestroy.turbo_stream.erbtemplate also renders_property_item(line 2-4), which calls@queued_property_ids.include?. Thedestroyaction does NOT set@queued_property_ids. This means removing a property from the queue via turbo stream will also 500 with aNoMethodErroron nil. The fix is incomplete without addressingdestroyas well.BLOCKERS
Same nil crash in
destroyaction.destroy.turbo_stream.erbrenders_property_item, which calls@queued_property_ids.include?. Thedestroyaction never sets@queued_property_ids. This is the same class of bug being fixed here. Thedestroyaction needs the same treatment:No test covers the turbo stream render path. The existing
POST /todayspec (line 51-56 inspec/requests/work_queue_items_spec.rb) only checks record count via the default HTML format. It does not requestas: :turbo_stream, so it never exercises the code path that crashed. A test like this would have caught the original bug and would prevent regression:The same coverage is needed for
DELETE /today/:idwith turbo stream format. New functionality (or bug fixes to existing functionality) with zero test coverage for the actual failure path is a BLOCKER per review policy.NITS
DRY opportunity: The query
WorkQueueItem.where(work_date: date).pluck(:property_id).to_setnow appears inindex(line 5) andcreate(line 30), and needs to appear indestroytoo. Consider extracting aset_queued_property_ids(date)private helper to keep this in one place. Not blocking, but three copies of the same query is a maintenance risk.Query after save: The
createaction queries@queued_property_idsafter@item.save, which means a fresh DB round-trip. This is fine for correctness and the dataset is small, but worth noting -- the newly saved item'sproperty_idis guaranteed to be in the result set.SOP COMPLIANCE
fix/500-queued-property-ids-nil. Convention requires{issue-number}-{kebab-case-purpose}(e.g.,74-fix-queued-property-ids-nil). Thefix/prefix format does not follow the convention.#74,Closes #74)PROCESS OBSERVATIONS
createbut the identical bug indestroymeans this PR would ship a known regression path. Fixing both in one PR reduces future change failure rate.create,destroy, and arguablyupdatehas zero test coverage. Adding turbo stream format specs for these actions would catch this entire class of ivar-missing bugs at CI time rather than in production.VERDICT: NOT APPROVED
Two blockers must be addressed:
destroyaction has the same@queued_property_idsnil bug -- fix it in this PR.createanddestroyto cover the actual failure path.PR #75 Re-Review
PREVIOUS FINDINGS STATUS
Finding 1: Same nil bug in
destroyaction -- RESOLVED. The second commit adds@queued_property_ids = WorkQueueItem.where(work_date: @date).pluck(:property_id).to_setat line 54 of the controller, correctly placed after@item.destroyand before the turbo stream render. Thedestroy.turbo_stream.erbtemplate renders_property_item, which calls@queued_property_ids.include?at line 11, so this fix is necessary and correct.Finding 2: Missing turbo stream test coverage -- RESOLVED. Two new test cases added to
spec/requests/work_queue_items_spec.rb:POST /todayturbo stream test (lines 57-65): sendstext/vnd.turbo-stream.htmlAccept header, asserts 200 status, correct media type, and presence ofqueued-badgein the response body.DELETE /today/:idturbo stream test (lines 84-92): same pattern, assertsbtn-addis present andqueued-badgeis absent after removal.Both test assertions align with the actual partial at
app/views/work_queue_items/_property_item.html.erb--queued-badgeappears when@queued_property_ids.include?(property.id)is true (line 16), andbtn-addappears when it is false (line 12). The tests directly exercise the code path that was crashing in production.DOMAIN REVIEW
Stack: Ruby on Rails, Turbo Streams, RSpec request specs.
WorkQueueItem.where(work_date: date).pluck(:property_id).to_setis consistent with howindexsets the same ivar (controller line 5). No DRY concern here -- extracting a method for a single-line query used in three places would be premature, and the three call sites have slightly different variable names for the date (@datevsdate).createsets@queued_property_idsafter@item.savesucceeds (line 30), so the newly created item's property_id is included in the set. Correct.destroysets@queued_property_idsafter@item.destroy(line 54), so the removed item's property_id is excluded from the set. Correct.pluckreturns raw IDs without loading AR objects.to_setcall ensures O(1) lookup in the partial'sinclude?check.BLOCKERS
None.
NITS
None. The fix is minimal and correctly scoped.
SOP COMPLIANCE
fix/500-queued-property-ids-nil-- descriptive of issue #74)PROCESS OBSERVATIONS
Clean fix for a production 500. The two-commit structure (fix create, then fix destroy + add tests) shows good response to review feedback. The turbo stream tests directly guard against regression of the nil ivar bug, which is the right testing strategy for this class of error.
VERDICT: APPROVED