A safe way to create class variables in a multisite environment.
This should allow plugins to set class variables that will not stomp on other plugins.
This commit is contained in:
parent
6700aed8ab
commit
3e13becf33
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue