From 657dff354494ed5906beb6fb9e2134c3e0f78792 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Tue, 27 Apr 2021 12:30:29 +0100 Subject: [PATCH] PERF: Remove N+1s from ThemeController#update and #show (#12842) These endpoints only return one `Theme` row, but the one-many relations were not being preloaded efficiently. This commit moves the `includes` statement to a scope, and makes use of it in `#index`, `#show`, and `#update`. --- app/controllers/admin/themes_controller.rb | 17 ++++------------- app/models/theme.rb | 13 +++++++++++++ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/app/controllers/admin/themes_controller.rb b/app/controllers/admin/themes_controller.rb index eec56598fe5..95f9bbe1e12 100644 --- a/app/controllers/admin/themes_controller.rb +++ b/app/controllers/admin/themes_controller.rb @@ -128,16 +128,7 @@ class Admin::ThemesController < Admin::AdminController end def index - @themes = Theme.order(:name).includes(:child_themes, - :parent_themes, - :remote_theme, - :theme_settings, - :settings_field, - :locale_fields, - :user, - :color_scheme, - theme_fields: :upload - ) + @themes = Theme.include_relations.order(:name) @color_schemes = ColorScheme.all.includes(:theme, color_scheme_colors: :color_scheme).to_a payload = { @@ -175,7 +166,7 @@ class Admin::ThemesController < Admin::AdminController end def update - @theme = Theme.find_by(id: params[:id]) + @theme = Theme.include_relations.find_by(id: params[:id]) raise Discourse::InvalidParameters.new(:id) unless @theme original_json = ThemeSerializer.new(@theme, root: false).to_json @@ -213,7 +204,7 @@ class Admin::ThemesController < Admin::AdminController if @theme.save update_default_theme - @theme.reload + @theme = Theme.include_relations.find(@theme.id) if (!disables_component && !enables_component) || theme_params.keys.size > 1 log_theme_change(original_json, @theme) @@ -249,7 +240,7 @@ class Admin::ThemesController < Admin::AdminController end def show - @theme = Theme.find_by(id: params[:id]) + @theme = Theme.include_relations.find_by(id: params[:id]) raise Discourse::InvalidParameters.new(:id) unless @theme render json: ThemeSerializer.new(@theme) diff --git a/app/models/theme.rb b/app/models/theme.rb index 1ac7d34489c..3c5ce549344 100644 --- a/app/models/theme.rb +++ b/app/models/theme.rb @@ -38,6 +38,19 @@ class Theme < ActiveRecord::Base where('user_selectable OR id = ?', SiteSetting.default_theme_id) } + scope :include_relations, -> { + includes(:child_themes, + :parent_themes, + :remote_theme, + :theme_settings, + :settings_field, + :locale_fields, + :user, + :color_scheme, + theme_fields: :upload + ) + } + def notify_color_change(color, scheme: nil) scheme ||= color.color_scheme changed_colors << color if color