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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 94a0e8e9b129d21e888c56a07658779a32b4a4a8
4
- data.tar.gz: a6004fe24c2671ca3153cbff26b7215059033ae9
3
+ metadata.gz: 8d8856c2619c65c969920012e0774c5852bc081a
4
+ data.tar.gz: 4aa3eeeba97039b149972437611479a9ca7e90f5
5
5
  SHA512:
6
- metadata.gz: f406387794a47eff446ba20ec4e8adac962adf50f393cc0946122d49d29de456ed3bb1adef6dd128228924a1aa8813c8ea2886883f301621c62c7848aadda2c5
7
- data.tar.gz: fd621cc380a647a82ebd9e888bd0e7c0ed2e10d3206ade3bc82e7623e8adf8e7d265181dbea98193cbc6b18df6fd6963b503c9202c656c238296773c1d3cabe8
6
+ metadata.gz: c8a855a064e37e57cbbad37a28c59e07d05415ccf865d28a947cda8283a831a442e6a45f1d05bfe472791ae16a6d7a56b1fedf9970606ae172197b0c50b11939
7
+ data.tar.gz: 8bd7e80e120213484c6057df63595f83938b7af8afc10300b354cf2125dd35ecc266f00933d3b883786b915c7ba878d67df56dbc9aa8a192075508c402b6a7dd
data/.gitignore CHANGED
@@ -10,3 +10,5 @@
10
10
  /log/
11
11
 
12
12
  bundle
13
+ .idea
14
+ *.iml
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) { new }
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
- key_class = respond_to?(:base_class) ? base_class : self
42
- "#{key_class.name.underscore}_obj".to_sym
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
@@ -1,3 +1,3 @@
1
1
  module RailsMultitenant
2
- VERSION = '0.8.0'
2
+ VERSION = '0.9.0'
3
3
  end
@@ -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.8.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-01-18 00:00:00.000000000 Z
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