rails_multitenant 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|