From 1480573c83f580a3a7eb5fef61ddbba69242032f Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 18 Jan 2024 20:39:30 -0500 Subject: [PATCH] Add `Account.auditable` scope, fix N+1 in admin/action_logs#index (#28812) --- .../admin/action_logs_controller.rb | 2 +- app/models/account.rb | 1 + app/models/admin/action_log_filter.rb | 2 +- spec/models/account_spec.rb | 19 +++++++++++++++++++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/action_logs_controller.rb b/app/controllers/admin/action_logs_controller.rb index 37a00ad225..8b8e83fde7 100644 --- a/app/controllers/admin/action_logs_controller.rb +++ b/app/controllers/admin/action_logs_controller.rb @@ -6,7 +6,7 @@ module Admin def index authorize :audit_log, :index? - @auditable_accounts = Account.where(id: Admin::ActionLog.select('distinct account_id')).select(:id, :username) + @auditable_accounts = Account.auditable.select(:id, :username) end private diff --git a/app/models/account.rb b/app/models/account.rb index c17de682e3..2fdfc2d514 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -126,6 +126,7 @@ class Account < ApplicationRecord scope :matches_username, ->(value) { where('lower((username)::text) LIKE lower(?)', "#{value}%") } scope :matches_display_name, ->(value) { where(arel_table[:display_name].matches("#{value}%")) } scope :without_unapproved, -> { left_outer_joins(:user).merge(User.approved.confirmed).or(remote) } + scope :auditable, -> { where(id: Admin::ActionLog.select(:account_id).distinct) } scope :searchable, -> { without_unapproved.without_suspended.where(moved_to_account_id: nil) } scope :discoverable, -> { searchable.without_silenced.where(discoverable: true).joins(:account_stat) } scope :by_recent_status, -> { includes(:account_stat).merge(AccountStat.order('last_status_at DESC NULLS LAST')).references(:account_stat) } diff --git a/app/models/admin/action_log_filter.rb b/app/models/admin/action_log_filter.rb index d413cb386d..f581af74e8 100644 --- a/app/models/admin/action_log_filter.rb +++ b/app/models/admin/action_log_filter.rb @@ -72,7 +72,7 @@ class Admin::ActionLogFilter end def results - scope = latest_action_logs.includes(:target) + scope = latest_action_logs.includes(:target, :account) params.each do |key, value| next if key.to_s == 'page' diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index d360d934d6..8488ccea45 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -835,6 +835,25 @@ RSpec.describe Account do end describe 'scopes' do + describe 'auditable' do + let!(:alice) { Fabricate :account } + let!(:bob) { Fabricate :account } + + before do + 2.times { Fabricate :action_log, account: alice } + end + + it 'returns distinct accounts with action log records' do + results = described_class.auditable + + expect(results.size) + .to eq(1) + expect(results) + .to include(alice) + .and not_include(bob) + end + end + describe 'alphabetic' do it 'sorts by alphabetic order of domain and username' do matches = [