diff --git a/app/models/group.rb b/app/models/group.rb index 491d9d3daa8..326d89781ab 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -1,13 +1,14 @@ # frozen_string_literal: true require_dependency 'enum' +require_dependency 'multisite_class_var' class Group < ActiveRecord::Base include HasCustomFields include AnonCacheInvalidator + include MultisiteClassVar - cattr_accessor :preloaded_custom_field_names - self.preloaded_custom_field_names = Set.new + multisite_class_var(:preloaded_custom_field_names) { Set.new } has_many :category_groups, dependent: :destroy has_many :group_users, dependent: :destroy diff --git a/app/models/post.rb b/app/models/post.rb index 853204830d0..45f5176334b 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -6,6 +6,7 @@ require_dependency 'post_analyzer' require_dependency 'validators/post_validator' require_dependency 'plugin/filter' require_dependency 'email_cook' +require_dependency 'multisite_class_var' require 'archetype' require 'digest/sha1' @@ -16,9 +17,9 @@ class Post < ActiveRecord::Base include Searchable include HasCustomFields include LimitedEdit + include MultisiteClassVar - cattr_accessor :permitted_create_params - self.permitted_create_params = Set.new + multisite_class_var(:permitted_create_params) { Set.new } # increase this number to force a system wide post rebake BAKED_VERSION = 1 diff --git a/app/models/topic_list.rb b/app/models/topic_list.rb index 375659dc5c8..3a3b005dfe5 100644 --- a/app/models/topic_list.rb +++ b/app/models/topic_list.rb @@ -1,29 +1,24 @@ require_dependency 'avatar_lookup' require_dependency 'primary_group_lookup' +require_dependency 'multisite_class_var' class TopicList include ActiveModel::Serialization + include MultisiteClassVar - cattr_accessor :preloaded_custom_fields - self.preloaded_custom_fields = Set.new + multisite_class_var(:preloaded_custom_fields) { Set.new } + multisite_class_var(:preload_callbacks) { Set.new } def self.on_preload(&blk) - (@preload ||= Set.new) << blk + preload_callbacks << blk end def self.cancel_preload(&blk) - if @preload - @preload.delete blk - if @preload.length == 0 - @preload = nil - end - end + preload_callbacks.delete(blk) end def self.preload(topics, object) - if @preload - @preload.each { |preload| preload.call(topics, object) } - end + preload_callbacks.each { |p| p.call(topics, object) } end attr_accessor :more_topics_url, @@ -117,8 +112,8 @@ class TopicList ft.topic_list = self end - if preloaded_custom_fields.present? - Topic.preload_custom_fields(@topics, preloaded_custom_fields) + if self.class.preloaded_custom_fields.present? + Topic.preload_custom_fields(@topics, self.class.preloaded_custom_fields) end TopicList.preload(@topics, self) diff --git a/lib/multisite_class_var.rb b/lib/multisite_class_var.rb new file mode 100644 index 00000000000..b21bca7d32f --- /dev/null +++ b/lib/multisite_class_var.rb @@ -0,0 +1,20 @@ +# Support for a class variable that is multisite aware. + +module MultisiteClassVar + + def self.included(base) + base.extend ClassMethods + end + + module ClassMethods + def multisite_class_var(name, &default) + @multisite_class_vars ||= {} + @multisite_class_vars[name] = {} + + define_singleton_method(name) do + @multisite_class_vars[name][RailsMultisite::ConnectionManagement.current_db] ||= default.call + end + end + end + +end diff --git a/lib/topic_view.rb b/lib/topic_view.rb index 57626225eb3..2127f3b5f75 100644 --- a/lib/topic_view.rb +++ b/lib/topic_view.rb @@ -2,8 +2,10 @@ require_dependency 'guardian' require_dependency 'topic_query' require_dependency 'filter_best_posts' require_dependency 'gaps' +require_dependency 'multisite_class_var' class TopicView + include MultisiteClassVar attr_reader :topic, :posts, :guardian, :filtered_posts, :chunk_size, :print, :message_bus_last_id attr_accessor :draft, :draft_key, :draft_sequence, :user_custom_fields, :post_custom_fields @@ -24,9 +26,7 @@ class TopicView @default_post_custom_fields ||= ["action_code_who"] end - def self.post_custom_fields_whitelisters - @post_custom_fields_whitelisters ||= Set.new - end + multisite_class_var(:post_custom_fields_whitelisters) { Set.new } def self.add_post_custom_fields_whitelister(&block) post_custom_fields_whitelisters << block diff --git a/spec/multisite/multisite_class_var_spec.rb b/spec/multisite/multisite_class_var_spec.rb new file mode 100644 index 00000000000..8787e6a9795 --- /dev/null +++ b/spec/multisite/multisite_class_var_spec.rb @@ -0,0 +1,65 @@ +require 'rails_helper' +require 'multisite_class_var' + +RSpec.describe MultisiteClassVar do + + it "will add the class variables" do + class_with_set = Class.new do + include MultisiteClassVar + multisite_class_var(:class_set) { Set.new } + multisite_class_var(:class_array) { Array.new } + end + + class_with_set.class_set << 'a' + class_with_set.class_array << 'c' + + expect(class_with_set.class_set).to contain_exactly('a') + expect(class_with_set.class_array).to contain_exactly('c') + end + + context "multisite environment" do + let(:conn) { RailsMultisite::ConnectionManagement } + + before do + @original_provider = SiteSetting.provider + SiteSetting.provider = SiteSettings::DbProvider.new(SiteSetting) + conn.config_filename = "spec/fixtures/multisite/two_dbs.yml" + conn.load_settings! + conn.remove_class_variable(:@@current_db) + end + + after do + [:@@db_spec_cache, :@@host_spec_cache, :@@default_spec].each do |class_variable| + conn.remove_class_variable(class_variable) + end + conn.set_current_db + end + + it "keeps the variable specific to the current site" do + class_with_set = Class.new do + include MultisiteClassVar + multisite_class_var(:class_set) { Set.new } + end + + conn.with_connection('default') do + expect(class_with_set.class_set).to be_blank + class_with_set.class_set << 'item0' + end + + conn.with_connection('second') do + expect(class_with_set.class_set).to be_blank + class_with_set.class_set << 'item1' + end + + conn.with_connection('default') do + expect(class_with_set.class_set).to contain_exactly('item0') + end + + conn.with_connection('second') do + expect(class_with_set.class_set).to contain_exactly('item1') + end + + end + end + +end