mirror of
https://github.com/discourse/discourse.git
synced 2025-06-16 22:42:30 +08:00
PERF: Reduce N+1s on theme admin page
This commit is contained in:
@ -107,6 +107,7 @@ class Admin::ThemesController < Admin::AdminController
|
|||||||
:remote_theme,
|
:remote_theme,
|
||||||
:theme_settings,
|
:theme_settings,
|
||||||
:settings_field,
|
:settings_field,
|
||||||
|
# :locale_fields, # Fails due to https://github.com/rails/rails/issues/34456
|
||||||
:user,
|
:user,
|
||||||
:color_scheme,
|
:color_scheme,
|
||||||
theme_fields: :upload
|
theme_fields: :upload
|
||||||
|
@ -142,13 +142,15 @@ class ColorScheme < ActiveRecord::Base
|
|||||||
@mutex = Mutex.new
|
@mutex = Mutex.new
|
||||||
|
|
||||||
def self.base_colors
|
def self.base_colors
|
||||||
|
return @base_colors if @base_colors
|
||||||
@mutex.synchronize do
|
@mutex.synchronize do
|
||||||
return @base_colors if @base_colors
|
return @base_colors if @base_colors
|
||||||
@base_colors = {}
|
base_colors = {}
|
||||||
File.readlines(BASE_COLORS_FILE).each do |line|
|
File.readlines(BASE_COLORS_FILE).each do |line|
|
||||||
matches = /\$([\w]+):\s*#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})(?:[;]|\s)/.match(line.strip)
|
matches = /\$([\w]+):\s*#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})(?:[;]|\s)/.match(line.strip)
|
||||||
@base_colors[matches[1]] = matches[2] if matches
|
base_colors[matches[1]] = matches[2] if matches
|
||||||
end
|
end
|
||||||
|
@base_colors = base_colors
|
||||||
end
|
end
|
||||||
@base_colors
|
@base_colors
|
||||||
end
|
end
|
||||||
|
@ -23,6 +23,7 @@ class Theme < ActiveRecord::Base
|
|||||||
belongs_to :remote_theme, autosave: true
|
belongs_to :remote_theme, autosave: true
|
||||||
|
|
||||||
has_one :settings_field, -> { where(target_id: Theme.targets[:settings], name: "yaml") }, class_name: 'ThemeField'
|
has_one :settings_field, -> { where(target_id: Theme.targets[:settings], name: "yaml") }, class_name: 'ThemeField'
|
||||||
|
has_many :locale_fields, -> { filter_locale_fields(I18n.fallbacks[I18n.locale]) }, class_name: 'ThemeField'
|
||||||
|
|
||||||
validate :component_validations
|
validate :component_validations
|
||||||
|
|
||||||
@ -357,7 +358,7 @@ class Theme < ActiveRecord::Base
|
|||||||
def translations(internal: false)
|
def translations(internal: false)
|
||||||
fallbacks = I18n.fallbacks[I18n.locale]
|
fallbacks = I18n.fallbacks[I18n.locale]
|
||||||
begin
|
begin
|
||||||
data = theme_fields.find_first_locale_fields([id], fallbacks).first&.translation_data(with_overrides: false, internal: internal)
|
data = locale_fields.first&.translation_data(with_overrides: false, internal: internal, fallback_fields: locale_fields)
|
||||||
return {} if data.nil?
|
return {} if data.nil?
|
||||||
best_translations = {}
|
best_translations = {}
|
||||||
fallbacks.reverse.each do |locale|
|
fallbacks.reverse.each do |locale|
|
||||||
|
@ -22,22 +22,23 @@ class ThemeField < ActiveRecord::Base
|
|||||||
.order("theme_sort_column")
|
.order("theme_sort_column")
|
||||||
}
|
}
|
||||||
|
|
||||||
scope :find_locale_fields, ->(theme_ids, locale_codes) {
|
scope :filter_locale_fields, ->(locale_codes) {
|
||||||
return none unless theme_ids.present? && locale_codes.present?
|
return none unless locale_codes.present?
|
||||||
|
|
||||||
find_by_theme_ids(theme_ids)
|
where(target_id: Theme.targets[:translations], name: locale_codes)
|
||||||
.where(target_id: Theme.targets[:translations], name: locale_codes)
|
|
||||||
.joins(self.sanitize_sql_array([
|
.joins(self.sanitize_sql_array([
|
||||||
"JOIN (
|
"JOIN (
|
||||||
SELECT * FROM (VALUES #{locale_codes.map { "(?)" }.join(",")}) as Y (locale_code, locale_sort_column)
|
SELECT * FROM (VALUES #{locale_codes.map { "(?)" }.join(",")}) as Y (locale_code, locale_sort_column)
|
||||||
) as Y ON Y.locale_code = theme_fields.name",
|
) as Y ON Y.locale_code = theme_fields.name",
|
||||||
*locale_codes.map.with_index { |code, index| [code, index] }
|
*locale_codes.map.with_index { |code, index| [code, index] }
|
||||||
]))
|
]))
|
||||||
.reorder("X.theme_sort_column", "Y.locale_sort_column")
|
.order("Y.locale_sort_column")
|
||||||
}
|
}
|
||||||
|
|
||||||
scope :find_first_locale_fields, ->(theme_ids, locale_codes) {
|
scope :find_first_locale_fields, ->(theme_ids, locale_codes) {
|
||||||
find_locale_fields(theme_ids, locale_codes)
|
find_by_theme_ids(theme_ids)
|
||||||
|
.filter_locale_fields(locale_codes)
|
||||||
|
.reorder("X.theme_sort_column", "Y.locale_sort_column")
|
||||||
.select("DISTINCT ON (X.theme_sort_column) *")
|
.select("DISTINCT ON (X.theme_sort_column) *")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,8 +129,8 @@ class ThemeField < ActiveRecord::Base
|
|||||||
ThemeTranslationParser.new(self, internal: internal).load
|
ThemeTranslationParser.new(self, internal: internal).load
|
||||||
end
|
end
|
||||||
|
|
||||||
def translation_data(with_overrides: true, internal: false)
|
def translation_data(with_overrides: true, internal: false, fallback_fields: nil)
|
||||||
fallback_fields = theme.theme_fields.find_locale_fields([theme.id], I18n.fallbacks[name])
|
fallback_fields ||= theme.theme_fields.filter_locale_fields(I18n.fallbacks[name])
|
||||||
|
|
||||||
fallback_data = fallback_fields.each_with_index.map do |field, index|
|
fallback_data = fallback_fields.each_with_index.map do |field, index|
|
||||||
begin
|
begin
|
||||||
|
@ -212,9 +212,10 @@ HTML
|
|||||||
let!(:en3) { ThemeField.create!(theme: theme3, target_id: Theme.targets[:translations], name: "en", value: "") }
|
let!(:en3) { ThemeField.create!(theme: theme3, target_id: Theme.targets[:translations], name: "en", value: "") }
|
||||||
|
|
||||||
describe "scopes" do
|
describe "scopes" do
|
||||||
it "find_locale_fields returns results in the correct order" do
|
it "filter_locale_fields returns results in the correct order" do
|
||||||
expect(ThemeField.find_locale_fields(
|
expect(ThemeField.find_by_theme_ids([theme3.id, theme.id, theme2.id])
|
||||||
[theme3.id, theme.id, theme2.id], ["en", "fr"]
|
.filter_locale_fields(
|
||||||
|
["en", "fr"]
|
||||||
)).to eq([en3, en1, fr1, en2, fr2])
|
)).to eq([en3, en1, fr1, en2, fr2])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user