rails_multitenant 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/CHANGELOG.md +6 -0
- data/lib/rails_multitenant/global_context_registry.rb +66 -3
- data/lib/rails_multitenant/version.rb +1 -1
- data/spec/current_spec.rb +118 -0
- data/spec/current_spec.rb.dis +80 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8d8856c2619c65c969920012e0774c5852bc081a
|
4
|
+
data.tar.gz: 4aa3eeeba97039b149972437611479a9ca7e90f5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8a855a064e37e57cbbad37a28c59e07d05415ccf865d28a947cda8283a831a442e6a45f1d05bfe472791ae16a6d7a56b1fedf9970606ae172197b0c50b11939
|
7
|
+
data.tar.gz: 8bd7e80e120213484c6057df63595f83938b7af8afc10300b354cf2125dd35ecc266f00933d3b883786b915c7ba878d67df56dbc9aa8a192075508c402b6a7dd
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
### 0.9.0
|
4
|
+
* Modify `Current.current` to return a specified default, when not already initialized, or `nil`
|
5
|
+
when no default is specified.
|
6
|
+
* Add `Current.provide_default` to optionally specify a default value for `Current.current`.
|
7
|
+
* Add `Current.current=` / `Current.current?` / `Current.current!` / `Current.as_current`.
|
8
|
+
|
3
9
|
### 0.8.0
|
4
10
|
* Switch usage of Fixnum to Integer for Ruby > 2.4
|
5
11
|
* Test with multiple Rubies
|
@@ -24,25 +24,88 @@ module RailsMultitenant
|
|
24
24
|
module Current
|
25
25
|
extend ActiveSupport::Concern
|
26
26
|
|
27
|
+
included do
|
28
|
+
class_attribute :default_provider, instance_writer: false
|
29
|
+
end
|
30
|
+
|
27
31
|
module ClassMethods
|
28
32
|
def current
|
29
|
-
GlobalContextRegistry.fetch(current_registry_obj) {
|
33
|
+
GlobalContextRegistry.fetch(current_registry_obj) { __current_default }
|
34
|
+
end
|
35
|
+
|
36
|
+
def current=(object)
|
37
|
+
raise "#{object} is not a #{self}" if object.present? && !object.is_a?(self)
|
38
|
+
GlobalContextRegistry.set(current_registry_obj, object)
|
39
|
+
__clear_dependents!
|
40
|
+
end
|
41
|
+
|
42
|
+
def current?
|
43
|
+
GlobalContextRegistry.get(current_registry_obj).present?
|
44
|
+
end
|
45
|
+
|
46
|
+
def current!
|
47
|
+
current || raise("No current #{name} set")
|
30
48
|
end
|
31
49
|
|
32
50
|
def clear_current!
|
33
51
|
GlobalContextRegistry.delete(current_registry_obj)
|
34
52
|
end
|
35
53
|
|
54
|
+
def as_current(object)
|
55
|
+
old_object = current if current?
|
56
|
+
self.current = object
|
57
|
+
yield
|
58
|
+
ensure
|
59
|
+
self.current = old_object
|
60
|
+
end
|
61
|
+
|
36
62
|
include RegistryDependentOn
|
37
63
|
|
64
|
+
def provide_default(provider = nil, &block)
|
65
|
+
self.default_provider = provider ? provider.to_proc : block
|
66
|
+
end
|
67
|
+
|
38
68
|
private
|
39
69
|
|
40
70
|
def current_registry_obj
|
41
|
-
|
42
|
-
|
71
|
+
return @current_registry_obj if @current_registry_obj
|
72
|
+
|
73
|
+
@current_registry_obj = "#{__key_class.name.underscore}_obj".to_sym
|
74
|
+
end
|
75
|
+
|
76
|
+
def current_registry_default_provider
|
77
|
+
"#{__key_class.name.underscore}_default_provider".to_sym
|
78
|
+
end
|
79
|
+
|
80
|
+
def __current_default
|
81
|
+
if self.default_provider
|
82
|
+
default = self.default_provider.call(self)
|
83
|
+
raise "#{default} is not a #{self}" if default.present? && !default.is_a?(self)
|
84
|
+
default
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def __clear_dependents!
|
89
|
+
GlobalContextRegistry.send(:dependencies_for, __key_class).each(&:clear_current!)
|
90
|
+
end
|
91
|
+
|
92
|
+
def __key_class
|
93
|
+
respond_to?(:base_class) ? base_class : self
|
43
94
|
end
|
44
95
|
end
|
45
96
|
|
97
|
+
def as_current
|
98
|
+
old_object = self.class.current if self.class.current?
|
99
|
+
self.class.current = self
|
100
|
+
yield
|
101
|
+
ensure
|
102
|
+
self.class.current = old_object
|
103
|
+
end
|
104
|
+
|
105
|
+
def current?
|
106
|
+
self.class.current? && self.equal?(self.class.current)
|
107
|
+
end
|
108
|
+
|
46
109
|
end
|
47
110
|
|
48
111
|
# This module allows you to have a current, thread-local instance
|
@@ -0,0 +1,118 @@
|
|
1
|
+
describe RailsMultitenant::GlobalContextRegistry::Current do
|
2
|
+
|
3
|
+
class TestClass
|
4
|
+
include RailsMultitenant::GlobalContextRegistry::Current
|
5
|
+
provide_default :new
|
6
|
+
|
7
|
+
attr_accessor :id
|
8
|
+
|
9
|
+
def initialize(id: :default)
|
10
|
+
@id = id
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class SubClass < TestClass
|
15
|
+
end
|
16
|
+
|
17
|
+
class DependentClass
|
18
|
+
include RailsMultitenant::GlobalContextRegistry::Current
|
19
|
+
provide_default { new }
|
20
|
+
global_context_dependent_on TestClass
|
21
|
+
end
|
22
|
+
|
23
|
+
class NoDefaultTestClass
|
24
|
+
include RailsMultitenant::GlobalContextRegistry::Current
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'current' do
|
28
|
+
it 'returns default value when supplied' do
|
29
|
+
expect(TestClass.current.id).to eq(:default)
|
30
|
+
expect(SubClass.current.id).to eq(:default)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'returns nil when no default supplied' do
|
34
|
+
expect(NoDefaultTestClass.current).to be_nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'current!' do
|
39
|
+
it 'returns current value when set' do
|
40
|
+
expect(TestClass.current.id).to eq(:default)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'raises an error when current not set' do
|
44
|
+
NoDefaultTestClass.clear_current!
|
45
|
+
expect { NoDefaultTestClass.current! }.to raise_error
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe 'current=' do
|
50
|
+
it 'stores the provided object' do
|
51
|
+
provided = TestClass.new(id: :provided)
|
52
|
+
TestClass.current = provided
|
53
|
+
expect(TestClass.current).to equal(provided)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'clears dependencies' do
|
57
|
+
dependent = DependentClass.current
|
58
|
+
TestClass.current = TestClass.new
|
59
|
+
expect(DependentClass.current).not_to equal(dependent)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe 'current?' do
|
64
|
+
it 'returns false when uninitialized' do
|
65
|
+
TestClass.clear_current!
|
66
|
+
expect(TestClass.current?).to be false
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'returns true when initialized' do
|
70
|
+
TestClass.current = TestClass.new
|
71
|
+
expect(TestClass.current?).to be true
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe 'as_current' do
|
76
|
+
let(:test_class1) { TestClass.new }
|
77
|
+
let(:test_class2) { TestClass.new }
|
78
|
+
|
79
|
+
it 'sets and restores current' do
|
80
|
+
TestClass.current = test_class1
|
81
|
+
TestClass.as_current(test_class2) do
|
82
|
+
expect(TestClass.current).to equal(test_class2)
|
83
|
+
end
|
84
|
+
expect(TestClass.current).to equal(test_class1)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'instance methods' do
|
89
|
+
describe 'current?' do
|
90
|
+
it 'returns false when not the current instance' do
|
91
|
+
TestClass.clear_current!
|
92
|
+
expect(TestClass.new.current?).to be false
|
93
|
+
|
94
|
+
TestClass.current = TestClass.new
|
95
|
+
expect(TestClass.new.current?).to be false
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'returns true when it is the current instance' do
|
99
|
+
test_class = TestClass.new
|
100
|
+
TestClass.current = test_class
|
101
|
+
expect(test_class.current?).to be true
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe 'as_current' do
|
106
|
+
let(:test_class1) { TestClass.new }
|
107
|
+
let(:test_class2) { TestClass.new }
|
108
|
+
|
109
|
+
it 'sets and restores current' do
|
110
|
+
TestClass.current = test_class1
|
111
|
+
test_class2.as_current do
|
112
|
+
expect(TestClass.current).to equal(test_class2)
|
113
|
+
end
|
114
|
+
expect(TestClass.current).to equal(test_class1)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# Create multiple orgs
|
2
|
+
# Create an item in each
|
3
|
+
# Make sure you can only see one org's item in one org
|
4
|
+
|
5
|
+
describe RailsMultitenant::GlobalContextRegistry::Current do
|
6
|
+
|
7
|
+
class Parent
|
8
|
+
include RailsMultitenant::GlobalContextRegistry::Current
|
9
|
+
|
10
|
+
attr_accessor :id
|
11
|
+
|
12
|
+
def initialize(id: 0)
|
13
|
+
@id = id
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Dependent
|
18
|
+
include RailsMultitenant::GlobalContextRegistry::Current
|
19
|
+
global_context_dependent_on Parent
|
20
|
+
end
|
21
|
+
|
22
|
+
class StepParent < Parent
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'current' do
|
26
|
+
expect(Parent.current.id).to eq(0)
|
27
|
+
expect(Parent.current).to eq(Parent.current)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'current=' do
|
31
|
+
Parent.current = Parent.new(id: 42)
|
32
|
+
expect(Parent.current.id).to eq(42)
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
it 'clear_current!' do
|
37
|
+
Parent.clear_current!
|
38
|
+
expect(Parent.current.id).to eq(0)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'current?' do
|
42
|
+
Parent.clear_current!
|
43
|
+
expect(Parent.current?).to be_falsey
|
44
|
+
Parent.current = Parent.new(id: 42)
|
45
|
+
expect(Parent.current?).to be_truthy
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'with dependencies' do
|
49
|
+
it 'dependent is cleared' do
|
50
|
+
Parent.current = Parent.new(id: 78)
|
51
|
+
Dependent.current = Dependent.new
|
52
|
+
Parent.current = Parent.new(id: 78)
|
53
|
+
expect(Dependent.current?).to be_falsey
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'dependent subclass is cleared' do
|
57
|
+
Parent.current = Parent.new(id: 78)
|
58
|
+
Dependent.current = Dependent.new
|
59
|
+
Parent.current = StepParent.new(id: 78)
|
60
|
+
expect(Dependent.current?).to be_falsey
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
#let(dependent_id) { Organization.current.id }
|
65
|
+
|
66
|
+
it 'dependent model subclass is cleared' do
|
67
|
+
#Organization.current = Organization.create!
|
68
|
+
DependsOnOrganization.current = DependsOnOrganization.create!
|
69
|
+
dependent_id = DependsOnOrganization.current.object_id
|
70
|
+
SubOrganization.current = SubOrganization.create!
|
71
|
+
expect(DependsOnOrganization.current.object_id).not_to eq(dependent_id)
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_multitenant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pat Breault
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -176,6 +176,8 @@ files:
|
|
176
176
|
- lib/rails_multitenant/version.rb
|
177
177
|
- rails_multitenant.gemspec
|
178
178
|
- spec/be_multitenant_on_matcher_spec.rb
|
179
|
+
- spec/current_spec.rb
|
180
|
+
- spec/current_spec.rb.dis
|
179
181
|
- spec/db/database.yml
|
180
182
|
- spec/db/schema.rb
|
181
183
|
- spec/external_item_spec.rb
|
@@ -215,6 +217,8 @@ test_files:
|
|
215
217
|
- spec/global_context_registry_spec.rb
|
216
218
|
- spec/external_item_spec.rb
|
217
219
|
- spec/item_subtype_spec.rb
|
220
|
+
- spec/current_spec.rb.dis
|
221
|
+
- spec/current_spec.rb
|
218
222
|
- spec/item_spec.rb
|
219
223
|
- spec/external_item_with_optional_org_spec.rb
|
220
224
|
- spec/db/schema.rb
|