Merge pull request #318: Query sidebar directs and shared rooms separately

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
3 changed files with 26 additions and 3 deletions
+3 -2
View File
@@ -2,8 +2,9 @@ class Users::SidebarsController < ApplicationController
DIRECT_PLACEHOLDERS = 20
def show
@direct_memberships, @other_memberships = Current.user.memberships.visible.with_ordered_room.partition { |membership| membership.room.direct? }
@direct_memberships = @direct_memberships.sort_by { |membership| membership.room.updated_at }.reverse
visible_memberships = Current.user.memberships.visible
@direct_memberships = visible_memberships.with_direct_rooms
@other_memberships = visible_memberships.with_ordered_room.without_direct_rooms
@direct_placeholder_users = find_direct_placeholder_users
end
+2 -1
View File
@@ -9,7 +9,8 @@ class Membership < ApplicationRecord
enum :involvement, %w[ invisible nothing mentions everything ].index_by(&:itself), prefix: :involved_in
scope :with_ordered_room, -> { includes(:room).joins(:room).order("LOWER(rooms.name)") }
scope :without_direct_rooms, -> { joins(:room).where.not(room: { type: "Rooms::Direct" }) }
scope :with_direct_rooms, -> { includes(:room).joins(:room).merge(Room.directs).order(rooms: { updated_at: :desc }) }
scope :without_direct_rooms, -> { joins(:room).merge(Room.without_directs) }
scope :visible, -> { where.not(involvement: :invisible) }
scope :unread, -> { where.not(unread_at: nil) }
@@ -27,4 +27,25 @@ class Users::SidebarsControllerTest < ActionDispatch::IntegrationTest
get user_sidebar_url
assert_select ".unread", count: users(:david).memberships.reject { |m| m.room.direct? || !m.unread? }.count
end
test "directs are ordered by room recency, not name" do
older = rooms(:david_and_jason)
newer = rooms(:david_and_kevin)
older.update_column :updated_at, 2.days.ago
newer.update_column :updated_at, 1.minute.ago
get user_sidebar_url
assert_operator @response.body.index(dom_id(newer, :list)), :<, @response.body.index(dom_id(older, :list))
end
test "shared rooms stay ordered by name" do
get user_sidebar_url
shared_ids = users(:david).rooms.without_directs.sort_by { |room| room.name.downcase }.map { |room| dom_id(room, :list) }
positions = shared_ids.map { |id| @response.body.index(id) }
assert positions.all?
assert_equal positions.sort, positions
end
end