From 20275e1fa754b1fdce7c40ecd2ede02d54070f17 Mon Sep 17 00:00:00 2001 From: Marcello Costagliola Date: Mon, 5 Oct 2026 17:17:29 +0200 Subject: [PATCH] Render the boosts a message has preloaded instead of querying them again Pages of messages load them with_presentation, which preloads each message's boosts with their boosters and avatars, but the boosts partial asked for message.boosts.ordered: a new query for every message, and the preloaded boosts went unused. Sort the preloaded boosts in Ruby. The boosts frame, whose message comes without them, still queries them in order with their boosters. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0142qgjggdJ2KDdGk7RF9Xm9 --- app/views/messages/boosts/_boosts.html.erb | 2 +- test/controllers/messages_caching_test.rb | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/views/messages/boosts/_boosts.html.erb b/app/views/messages/boosts/_boosts.html.erb index ca25d74..61636ea 100644 --- a/app/views/messages/boosts/_boosts.html.erb +++ b/app/views/messages/boosts/_boosts.html.erb @@ -2,7 +2,7 @@
- <%= render partial: "messages/boosts/boost", collection: message.boosts.ordered.includes(:booster) %> + <%= render partial: "messages/boosts/boost", collection: message.boosts.loaded? ? message.boosts.sort_by(&:created_at) : message.boosts.ordered.includes(:booster) %>
<%= turbo_frame_tag message, :new_boost do %> diff --git a/test/controllers/messages_caching_test.rb b/test/controllers/messages_caching_test.rb index 3a7c4c8..f071da0 100644 --- a/test/controllers/messages_caching_test.rb +++ b/test/controllers/messages_caching_test.rb @@ -53,6 +53,20 @@ class MessagesCachingTest < ActionDispatch::IntegrationTest end end + test "messages render their preloaded boosts in order without querying them again" do + earlier = messages(:fourth).boosts.create! booster: users(:jason), content: "🥇", created_at: 1.day.ago + in_order = [ dom_id(earlier), dom_id(boosts(:fourth_by_bender)) ] + + assert_no_queries_match(/ORDER BY "boosts"/) do + get room_messages_url(rooms(:watercooler)) + end + assert_response :success + assert_equal in_order, css_select("##{dom_id(messages(:fourth), :boosts)} .boost").map { it["id"] } + + get message_boosts_url(messages(:fourth)) + assert_equal in_order, css_select("##{dom_id(messages(:fourth), :boosts)} .boost").map { it["id"] } + end + private def with_memory_cache old_cache = Rails.cache