Merge pull request #312: Find the messages a refresh replaces through an index

Reviewed and merged by GPT on behalf of DHH.
This commit is contained in:
GPT on behalf of DHH
2026-10-07 10:32:12 +02:00
4 changed files with 27 additions and 2 deletions
+4 -1
View File
@@ -36,7 +36,10 @@ module Message::Pagination
scope :page_after, ->(message) { after(message).first_page }
scope :page_created_since, ->(time) { where("created_at > ?", time).first_page }
scope :page_updated_since, ->(time) { where("updated_at > ?", time).last_page }
# Sorting on +created_at, which no index covers, has SQLite find the few messages updated since
# through (room_id, updated_at) and sort just those, instead of walking the whole room by
# (room_id, created_at) looking for them.
scope :page_updated_since, ->(time) { Page.load(where("updated_at > ?", time).reorder(Arel.sql("+messages.created_at")), :last, PAGE_SIZE) }
end
class_methods do
@@ -0,0 +1,5 @@
class AddRoomIdAndUpdatedAtIndexToMessages < ActiveRecord::Migration[8.2]
def change
add_index :messages, %i[ room_id updated_at ], if_not_exists: true
end
end
Generated
+2 -1
View File
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.2].define(version: 2026_10_04_225000) do
ActiveRecord::Schema[8.2].define(version: 2026_10_05_022000) do
create_table "accounts", force: :cascade do |t|
t.datetime "created_at", null: false
t.text "custom_styles"
@@ -102,6 +102,7 @@ ActiveRecord::Schema[8.2].define(version: 2026_10_04_225000) do
t.datetime "updated_at", null: false
t.index ["creator_id"], name: "index_messages_on_creator_id"
t.index ["room_id", "created_at"], name: "index_messages_on_room_id_and_created_at"
t.index ["room_id", "updated_at"], name: "index_messages_on_room_id_and_updated_at"
t.index ["room_id"], name: "index_messages_on_room_id"
end
+16
View File
@@ -0,0 +1,16 @@
require "test_helper"
class Message::PaginationTest < ActiveSupport::TestCase
test "messages updated since a time are the newest page of them, in creation order" do
room = rooms(:watercooler)
first, second, third = room.messages.ordered.first(3)
travel 1.minute do
[ third, first, second ].each(&:touch)
stub_const(Message::Pagination, :PAGE_SIZE, 2) do
assert_equal [ second, third ], room.messages.page_updated_since(30.seconds.ago).to_a
end
end
end
end