Skip to content

Commit

Permalink
Clear Dependency Chain (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
gremerritt authored Mar 16, 2023
1 parent aa2eeec commit 76bee9b
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 8 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## 0.18.1
* Fix issue where only direct dependencies of `Current` and `CurrentInstance` classes are cleared.

## 0.18.0
* Add better support for registry dependencies in a development environment where classes may be reloaded.
* Add a `global_context_mutually_dependent_on` method to support registering bidirectional references.
Expand Down
12 changes: 9 additions & 3 deletions lib/rails_multitenant/global_context_registry/current.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ def current!
current || raise("No current #{name} set")
end

def clear_current!
def clear_current!(cleared = nil)
GlobalContextRegistry.delete(current_registry_obj)
__clear_dependents!(cleared)
end

def as_current(object)
Expand Down Expand Up @@ -73,8 +74,13 @@ def __current_default
end
end

def __clear_dependents!
GlobalContextRegistry.send(:dependencies_for, __key_class).each(&:clear_current!)
def __clear_dependents!(initial_cleared = nil)
GlobalContextRegistry.send(:dependencies_for, __key_class).tap do |dependencies|
next unless dependencies.present?

(cleared = initial_cleared || []) << self
dependencies.each { |obj| obj.clear_current!(cleared) unless cleared.include?(obj) }
end
end

def __key_class
Expand Down
13 changes: 10 additions & 3 deletions lib/rails_multitenant/global_context_registry/current_instance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,22 @@ def as_current(model)
self.current = old_model
end

def clear_current!
def clear_current!(cleared = nil)
GlobalContextRegistry.delete(current_instance_registry_obj)
__clear_dependents!(cleared)
end

private

def __clear_dependents!
def __clear_dependents!(initial_cleared = nil)
key_class = respond_to?(:base_class) ? base_class : self
GlobalContextRegistry.send(:dependencies_for, key_class).each(&:clear_current!)

GlobalContextRegistry.send(:dependencies_for, key_class).tap do |dependencies|
next unless dependencies.present?

(cleared = initial_cleared || []) << self
dependencies.each { |obj| obj.clear_current!(cleared) unless cleared.include?(obj) }
end
end

def current_instance_registry_id
Expand Down
2 changes: 1 addition & 1 deletion lib/rails_multitenant/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module RailsMultitenant
VERSION = '0.18.0'
VERSION = '0.18.1'
end
26 changes: 25 additions & 1 deletion spec/rails_multitenant/global_context_registry/current_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,15 @@ def initialize(id: :default)
before do
stub_const('SubClass', Class.new(TestClass))
stub_const('DependentClass', dependent_class)
stub_const('CyclicallyDependentClass1', cyclically_dependent_class1)
stub_const('CyclicallyDependentClass2', cyclically_dependent_class2)
stub_const('BiDependentClass', bidependent_class)
stub_const('NoDefaultTestClass', no_default_test_class)

DependentClass.global_context_dependent_on TestClass
DependentClass.global_context_dependent_on CyclicallyDependentClass2
CyclicallyDependentClass1.global_context_dependent_on DependentClass
CyclicallyDependentClass2.global_context_dependent_on CyclicallyDependentClass1
BiDependentClass.global_context_mutually_dependent_on TestClass
end

Expand All @@ -29,6 +34,20 @@ def initialize(id: :default)
end
end

let(:cyclically_dependent_class1) do
Class.new do
include RailsMultitenant::GlobalContextRegistry::Current
provide_default { new }
end
end

let(:cyclically_dependent_class2) do
Class.new do
include RailsMultitenant::GlobalContextRegistry::Current
provide_default { new }
end
end

let(:bidependent_class) do
Class.new do
include RailsMultitenant::GlobalContextRegistry::Current
Expand Down Expand Up @@ -73,8 +92,13 @@ def initialize(id: :default)

it "clears dependencies" do
dependent = DependentClass.current
cyclically_dependent1 = CyclicallyDependentClass1.current
cyclically_dependent2 = CyclicallyDependentClass1.current

TestClass.current = TestClass.new
expect(dependent_class.current).not_to equal(dependent)
expect(DependentClass.current).not_to equal(dependent)
expect(CyclicallyDependentClass1.current).not_to equal(cyclically_dependent1)
expect(CyclicallyDependentClass2.current).not_to equal(cyclically_dependent2)
end

it "clears bidirectional dependencies" do
Expand Down

0 comments on commit 76bee9b

Please sign in to comment.