Files
once-campfire/app/controllers/rooms_controller.rb
T
Marcello Costagliola 7b16014f01 Delete a room's messages in a job, one transaction each
Room#destroy destroyed every message inside the room's own
transaction, which holds SQLite's write lock until the last one: on a
room with many messages, every other write in the app waited and
failed. The request now takes the room away from its members and
leaves the rest to Room::DestroyJob, which destroys the messages one
at a time, each in its own short transaction, and then the room.

An open room is closed in the request, so that someone who joins the
account before the job ends isn't given it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bj8KnxpTf9sj2Ysa8aLAVa
2026-10-06 13:57:05 +02:00

64 lines
1.6 KiB
Ruby

class RoomsController < ApplicationController
before_action :set_room, only: %i[ show destroy ]
before_action :ensure_can_administer, only: %i[ destroy ]
before_action :remember_last_room_visited, only: :show
def index
redirect_to room_url(Current.user.rooms.last)
end
def show
@messages = find_messages
end
def destroy
@room.destroy_later
broadcast_remove_room
redirect_to root_url
end
private
def set_room
if room = room_scope.find_by(id: params[:room_id] || params[:id])
@room = room
else
redirect_to root_url, alert: "Room not found or inaccessible"
end
end
# Subclasses narrow this to the room types they're allowed to act on, so that one
# room namespace can't be used to reach another's rooms.
def room_scope
Current.user.rooms
end
def ensure_can_administer
head :forbidden unless Current.user.can_administer?(@room)
end
def ensure_permission_to_create_rooms
if Current.account.settings.restrict_room_creation_to_administrators? && !Current.user.administrator?
head :forbidden
end
end
def find_messages
messages = @room.messages.with_presentation
if params[:message_id].present? && (show_first_message = messages.find_by(id: params[:message_id]))
@messages = messages.page_around(show_first_message)
else
@messages = messages.last_page
end
end
def room_params
params.require(:room).permit(:name)
end
def broadcast_remove_room
broadcast_remove_to :rooms, target: [ @room, :list ]
end
end