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`.
This commit is contained in:
David Taylor 2021-04-27 12:30:29 +01:00 committed by GitHub
parent 40e545dc30
commit 657dff3544
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 13 deletions

View File

@ -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)

View File

@ -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