mongoid_ability 0.0.11 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +18 -13
  3. data/lib/mongoid_ability.rb +8 -2
  4. data/lib/mongoid_ability/ability.rb +32 -30
  5. data/lib/mongoid_ability/accessible_query_builder.rb +61 -41
  6. data/lib/mongoid_ability/lock.rb +16 -29
  7. data/lib/mongoid_ability/owner.rb +6 -22
  8. data/lib/mongoid_ability/resolve_default_locks.rb +15 -0
  9. data/lib/mongoid_ability/resolve_inherited_locks.rb +32 -0
  10. data/lib/mongoid_ability/resolve_locks.rb +34 -0
  11. data/lib/mongoid_ability/resolve_owner_locks.rb +25 -0
  12. data/lib/mongoid_ability/subject.rb +28 -32
  13. data/lib/mongoid_ability/version.rb +1 -1
  14. data/test/mongoid_ability/ability_role_test.rb +11 -5
  15. data/test/mongoid_ability/ability_test.rb +67 -91
  16. data/test/mongoid_ability/accessible_query_builder_test.rb +9 -5
  17. data/test/mongoid_ability/can_options_test.rb +17 -0
  18. data/test/mongoid_ability/lock_test.rb +51 -70
  19. data/test/mongoid_ability/owner_locks_test.rb +42 -0
  20. data/test/mongoid_ability/owner_test.rb +12 -39
  21. data/test/mongoid_ability/resolve_default_locks_test.rb +27 -0
  22. data/test/mongoid_ability/resolve_inherited_locks_test.rb +49 -0
  23. data/test/mongoid_ability/resolve_locks_test.rb +25 -0
  24. data/test/mongoid_ability/resolve_owner_locks_test.rb +50 -0
  25. data/test/mongoid_ability/subject_accessible_by_test.rb +135 -0
  26. data/test/mongoid_ability/subject_test.rb +20 -201
  27. data/test/support/test_classes.rb +136 -61
  28. data/test/test_helper.rb +3 -2
  29. metadata +20 -5
  30. data/lib/mongoid_ability/ability_resolver.rb +0 -42
  31. data/test/mongoid_ability/ability_resolver_test.rb +0 -78
@@ -0,0 +1,135 @@
1
+ require 'test_helper'
2
+
3
+ module MongoidAbility
4
+ describe '.accessible_by' do
5
+
6
+ let(:role_1) { MyRole.new }
7
+ let(:role_2) { MyRole.new }
8
+ let(:owner) { MyOwner.new(my_roles: [ role_1, role_2 ]) }
9
+ let(:ability) { Ability.new(owner) }
10
+
11
+ before do
12
+ MySubject.default_locks = [ MyLock.new(subject_type: MySubject, action: :read, outcome: true) ]
13
+ MySubject1.default_locks = []
14
+
15
+ @my_subject = MySubject.create!
16
+ @my_subject_1 = MySubject1.create!
17
+ end
18
+
19
+ # =====================================================================
20
+
21
+ describe 'default locks' do
22
+ describe 'when open' do
23
+ it 'returns everything' do
24
+ MySubject.accessible_by(ability, :read).to_a.must_include @my_subject
25
+ MySubject.accessible_by(ability, :read).to_a.must_include @my_subject_1
26
+ end
27
+ end
28
+
29
+ describe 'when closed' do
30
+ before do
31
+ MySubject.default_locks = [ MyLock.new(subject_type: MySubject, action: :read, outcome: false) ]
32
+ MySubject1.default_locks = []
33
+ end
34
+
35
+ it 'returns nothing' do
36
+ MySubject.accessible_by(ability, :read).to_a.wont_include @my_subject
37
+ MySubject.accessible_by(ability, :read).to_a.wont_include @my_subject_1
38
+ end
39
+ end
40
+ end
41
+
42
+ # ---------------------------------------------------------------------
43
+
44
+ describe 'subject_type lock' do
45
+ describe 'on roles' do
46
+ it 'overrides default lock' do
47
+ role_1.my_locks = [ MyLock.new(subject_type: MySubject, action: :read, outcome: false) ]
48
+ MySubject.accessible_by(ability, :read).to_a.must_be :empty?
49
+ end
50
+
51
+ it 'takes the most permissive of roles' do
52
+ role_1.my_locks = [ MyLock.new(subject_type: MySubject, action: :read, outcome: false) ]
53
+ role_2.my_locks = [ MyLock.new(subject_type: MySubject, action: :read, outcome: true) ]
54
+ MySubject.accessible_by(ability, :read).to_a.must_include @my_subject
55
+ MySubject.accessible_by(ability, :read).to_a.must_include @my_subject_1
56
+ end
57
+ end
58
+
59
+ describe 'on user' do
60
+ it 'overrides default lock' do
61
+ owner.my_locks = [ MyLock.new(subject_type: MySubject, action: :read, outcome: false) ]
62
+ MySubject.accessible_by(ability, :read).to_a.must_be :empty?
63
+ end
64
+
65
+ it 'overrides role locks' do
66
+ role_1.my_locks = [ MyLock.new(subject_type: MySubject, action: :read, outcome: false) ]
67
+ owner.my_locks = [ MyLock.new(subject_type: MySubject, action: :read, outcome: true) ]
68
+ MySubject.accessible_by(ability, :read).to_a.must_include @my_subject
69
+ MySubject.accessible_by(ability, :read).to_a.must_include @my_subject_1
70
+ end
71
+ end
72
+ end
73
+
74
+ # ---------------------------------------------------------------------
75
+
76
+ describe 'subject_id lock' do
77
+ describe 'on roles' do
78
+ it 'overrides default lock' do
79
+ role_1.my_locks = [ MyLock.new(subject: @my_subject, action: :read, outcome: false) ]
80
+ MySubject1.accessible_by(ability, :read).to_a.wont_include @my_subject
81
+ end
82
+
83
+ it 'overrides default negative lock' do
84
+ MySubject.default_locks = [ MyLock.new(subject_type: MySubject, action: :read, outcome: false) ]
85
+ role_1.my_locks = [ MyLock.new(subject: @my_subject, action: :read, outcome: true) ]
86
+ MySubject.accessible_by(ability, :read).to_a.must_include @my_subject
87
+ end
88
+
89
+ it 'overrides subject_type lock' do
90
+ role_1.my_locks = [ MyLock.new(subject_type: MySubject, action: :read, outcome: false) ]
91
+ role_2.my_locks = [ MyLock.new(subject: @my_subject, action: :read, outcome: true) ]
92
+ MySubject.accessible_by(ability, :read).to_a.must_include @my_subject
93
+ end
94
+
95
+ it 'takes the most permissive of roles' do
96
+ role_1.my_locks = [ MyLock.new(subject: @my_subject, action: :read, outcome: true) ]
97
+ role_2.my_locks = [ MyLock.new(subject: @my_subject, action: :read, outcome: false) ]
98
+ MySubject.accessible_by(ability, :read).to_a.must_include @my_subject
99
+ end
100
+
101
+ describe 'for subclasses' do
102
+ it 'overrides default negative lock' do
103
+ MySubject.default_locks = [ MyLock.new(subject_type: MySubject1, action: :read, outcome: false) ]
104
+ role_1.my_locks = [ MyLock.new(subject: @my_subject_1, action: :read, outcome: true) ]
105
+ MySubject.accessible_by(ability, :read).to_a.wont_include @my_subject
106
+ MySubject.accessible_by(ability, :read).to_a.must_include @my_subject_1
107
+ end
108
+ end
109
+ end
110
+
111
+ describe 'on user' do
112
+ it 'overrides default lock' do
113
+ owner.my_locks = [ MyLock.new(subject_type: MySubject, action: :read, outcome: false) ]
114
+ MySubject.accessible_by(ability, :read).to_a.must_be :empty?
115
+ end
116
+
117
+ it 'overrides subject_type lock' do
118
+ owner.my_locks = [
119
+ MyLock.new(subject_type: MySubject, action: :read, outcome: false),
120
+ MyLock.new(subject_type: MySubject1, action: :read, outcome: true)
121
+ ]
122
+ MySubject.accessible_by(ability, :read).to_a.wont_include @my_subject
123
+ MySubject.accessible_by(ability, :read).to_a.must_include @my_subject_1
124
+ end
125
+
126
+ it 'overrides role locks' do
127
+ role_1.my_locks = [ MyLock.new(subject_type: MySubject, action: :read, outcome: false) ]
128
+ owner.my_locks = [ MyLock.new(subject_type: MySubject, action: :read, outcome: true) ]
129
+ MySubject.accessible_by(ability, :read).to_a.must_include @my_subject
130
+ end
131
+ end
132
+ end
133
+
134
+ end
135
+ end
@@ -2,222 +2,41 @@ require 'test_helper'
2
2
 
3
3
  module MongoidAbility
4
4
  describe Subject do
5
+ describe '.default_locks' do
5
6
 
6
- def subject_type_lock subject_cls, outcome
7
- TestLock.new(subject_type: subject_cls.to_s, action: :read, outcome: outcome)
8
- end
9
-
10
- def subject_lock subject, outcome
11
- TestLock.new(subject: subject, action: :read, outcome: outcome)
12
- end
13
-
14
- # ---------------------------------------------------------------------
15
-
16
- subject { SubjectTest.new }
17
-
18
- let(:subject_single_test) { SubjectSingleTest.create! }
19
-
20
- let(:subject_test_1) { SubjectTestOne.create! }
21
- let(:subject_test_2) { SubjectTestTwo.create! }
22
-
23
- let(:role_1) { TestRole.new }
24
- let(:role_2) { TestRole.new }
25
-
26
- let(:user) { TestUser.new(roles: [role_1, role_2]) }
27
- let(:ability) { Ability.new(user) }
28
-
29
- # =====================================================================
30
-
31
- describe 'class methods' do
32
- it '.default_locks' do
33
- subject.class.must_respond_to :default_locks
34
- subject.class.default_locks.must_be_kind_of Array
35
- end
36
-
37
- it '.default_lock' do
38
- subject.class.must_respond_to :default_lock
39
- end
40
-
41
- it 'default_locks_with_inherited' do
42
- subject.class.must_respond_to :default_locks_with_inherited
43
- subject.class.default_locks_with_inherited.must_be_kind_of Array
44
- subject_test_1.class.default_locks_with_inherited.must_equal subject.class.default_locks
45
- end
46
-
47
- describe '.default_lock' do
48
- it 'sets up new Lock' do
49
- lock = subject.class.default_locks.first
50
- subject.class.default_locks.length.must_equal 1
51
- lock.subject_type.must_equal subject.class.model_name
52
- lock.subject_id.must_be_nil
53
- lock.action.must_equal :read
54
- end
55
-
56
- describe 'when trying to insert another lock for same action' do
57
- before { subject.class.default_lock :read, false }
58
- after { subject.class.default_lock :read, true }
59
-
60
- it 'does not create duplicate' do
61
- subject.class.default_locks.select{ |l| l.action == :read }.length.must_equal 1
62
- end
63
- it 'sets the new outcome' do
64
- subject.class.default_locks.select{ |l| l.action == :read }.first.outcome.must_equal false
65
- end
66
- end
67
- end
7
+ before do
8
+ MySubject.default_locks = []
9
+ MySubject1.default_locks = []
68
10
 
69
- # =====================================================================
70
-
71
- describe '.ancestors_with_default_locks' do
72
- it 'lists ancestors with default locks' do
73
- subject_test_1.class.ancestors_with_default_locks.must_equal [subject.class]
74
- end
11
+ MySubject.default_lock MyLock, :read, true
12
+ MySubject1.default_lock MyLock1, :update, false
75
13
  end
76
14
 
77
- describe '.self_and_ancestors_with_default_locks' do
78
- it 'lists self and ancestors with default locks' do
79
- subject_test_1.class.self_and_ancestors_with_default_locks.must_equal [subject_test_1.class, subject.class]
80
- end
15
+ it 'stores them' do
16
+ MySubject.default_locks.map(&:action).map(&:to_s).sort.must_equal %w(read)
17
+ MySubject1.default_locks.map(&:action).map(&:to_s).sort.must_equal %w(update)
81
18
  end
82
19
 
83
- # =====================================================================
84
-
85
- describe '.accessible_by' do
20
+ describe 'prevents conflicts' do
86
21
  before do
87
- subject_test_1
88
- subject_test_2
89
- subject_single_test
22
+ # FIXME: this permanently adjusts the default test locks – ideally do this other way, stubs etc.
23
+ MySubject.default_lock MyLock, :read, false
24
+ MySubject.default_lock MyLock1, :read, false
90
25
  end
91
26
 
92
- # ---------------------------------------------------------------------
93
-
94
- describe 'default locks' do
95
- it 'returns everything when open' do
96
- subject.class.stub(:default_locks, [ subject_type_lock(subject.class, true) ]) do
97
- subject.class.accessible_by(ability).must_include subject_test_1
98
- subject.class.accessible_by(ability).must_include subject_test_2
99
- end
100
- end
101
-
102
- describe 'single class' do
103
- it 'returns everything when open' do
104
- subject_single_test.class.stub(:default_locks, [ subject_type_lock(subject_single_test.class, true) ]) do
105
- subject_single_test.class.accessible_by(ability).must_include subject_single_test
106
- end
107
- end
108
- end
109
-
110
- it 'returns nothing when closed' do
111
- subject.class.stub(:default_locks, [ subject_type_lock(subject.class, false) ]) do
112
- subject.class.accessible_by(ability).must_be :empty?
113
- end
114
- end
115
-
116
- describe 'single class' do
117
- it 'returns nothing when closed' do
118
- subject_single_test.class.stub(:default_locks, [ subject_type_lock(subject_single_test.class, false) ]) do
119
- subject_single_test.class.accessible_by(ability).wont_include subject_single_test
120
- end
121
- end
122
- end
27
+ it 'does not allow multiple locks for same action' do
28
+ MySubject.default_locks.select{ |l| l.action == :read }.count.must_equal 1
123
29
  end
124
30
 
125
- # ---------------------------------------------------------------------
126
-
127
- describe 'subject_type lock' do
128
- describe 'on roles' do
129
- it 'overrides default lock' do
130
- role_1.test_locks = [ subject_type_lock(subject.class, false) ]
131
- subject.class.accessible_by(ability).must_be :empty?
132
- end
133
- it 'takes the most permissive of roles' do
134
- role_1.test_locks = [ subject_type_lock(subject.class, false) ]
135
- role_2.test_locks = [ subject_type_lock(subject.class, true) ]
136
- subject.class.accessible_by(ability).must_include subject_test_1
137
- subject.class.accessible_by(ability).must_include subject_test_2
138
- end
139
- end
140
-
141
- describe 'on user' do
142
- it 'overrides default lock' do
143
- user.test_locks = [ subject_type_lock(subject.class, false) ]
144
- subject.class.accessible_by(ability).must_be :empty?
145
- end
146
- it 'overrides role locks' do
147
- role_1.test_locks = [ subject_type_lock(subject.class, false) ]
148
- user.test_locks = [ subject_type_lock(subject.class, true) ]
149
- subject.class.accessible_by(ability).must_include subject_test_1
150
- subject.class.accessible_by(ability).must_include subject_test_2
151
- end
152
- end
31
+ it 'replace existing locks with new attributes' do
32
+ MySubject.default_locks.detect{ |l| l.action == :read }.outcome.must_equal false
153
33
  end
154
34
 
155
- # ---------------------------------------------------------------------
156
-
157
- describe 'subject_id lock' do
158
- describe 'on roles' do
159
- it 'overrides default lock' do
160
- role_1.test_locks = [ subject_lock(subject_test_1, false) ]
161
- subject.class.accessible_by(ability).wont_include subject_test_1
162
- end
163
-
164
- it 'overrides default negative lock' do
165
- subject.class.stub(:default_locks, [ subject_type_lock(subject_test_1.class, false) ]) do
166
- role_1.test_locks = [ subject_lock(subject_test_1, true) ]
167
- subject.class.accessible_by(ability).must_include subject_test_1
168
- end
169
- end
170
-
171
- it 'overrides subject_type lock' do
172
- role_1.test_locks = [ subject_type_lock(subject_test_2.class, false) ]
173
- role_2.test_locks = [ subject_lock(subject_test_2, true) ]
174
- subject.class.accessible_by(ability).must_include subject_test_2
175
- end
176
-
177
- it 'overrides default negative lock' do
178
- subject.class.stub(:default_locks, [ subject_type_lock(subject_test_2.class, false) ]) do
179
- role_2.test_locks = [ subject_lock(subject_test_2, true) ]
180
- subject.class.accessible_by(ability).wont_include subject_test_1
181
- subject.class.accessible_by(ability).must_include subject_test_2
182
- end
183
- end
184
-
185
- it 'takes the most permissive of roles' do
186
- role_1.test_locks = [ subject_lock(subject_test_2, false) ]
187
- role_2.test_locks = [ subject_lock(subject_test_2, true) ]
188
- subject.class.accessible_by(ability).must_include subject_test_2
189
- end
190
- end
191
-
192
- describe 'on user' do
193
- it 'overrides default lock' do
194
- user.test_locks = [ subject_lock(subject_test_1, false) ]
195
- subject.class.accessible_by(ability).wont_include subject_test_1
196
- subject.class.accessible_by(ability).must_include subject_test_2
197
- end
198
-
199
- it 'overrides subject_type lock' do
200
- user.test_locks = [ subject_type_lock(subject_test_1.class, true), subject_lock(subject_test_1, false) ]
201
- subject.class.accessible_by(ability).wont_include subject_test_1
202
- end
203
-
204
- it 'overrides role locks' do
205
- role_1.test_locks = [ subject_lock(subject_test_2, false) ]
206
- user.test_locks = [ subject_lock(subject_test_2, true) ]
207
- subject.class.accessible_by(ability).must_include subject_test_2
208
- end
209
-
210
- it 'overrides default negative lock' do
211
- subject.class.stub(:default_locks, [ subject_type_lock(subject_test_2.class, false) ]) do
212
- user.test_locks = [ subject_lock(subject_test_2, true) ]
213
- subject.class.accessible_by(ability).must_include subject_test_2
214
- end
215
- end
216
- end
35
+ it 'replaces existing locks with new one' do
36
+ MySubject.default_locks.detect{ |l| l.action == :read }.class.must_equal MyLock1
217
37
  end
218
-
219
38
  end
39
+
220
40
  end
221
41
  end
222
-
223
42
  end
@@ -1,86 +1,161 @@
1
- class TestLock
2
- include Mongoid::Document
3
- include MongoidAbility::Lock
1
+ module MongoidAbility
2
+ class MyLock
3
+ include Mongoid::Document
4
+ include MongoidAbility::Lock
5
+ embedded_in :owner, polymorphic: true
6
+ end
4
7
 
5
- embedded_in :owner, polymorphic: true
6
- end
8
+ class MyLock1 < MyLock
9
+ def calculated_outcome opts={}
10
+ opts.fetch(:override, outcome)
11
+ end
12
+ end
7
13
 
8
- class TestLockSub < TestLock
9
- end
14
+ # ---------------------------------------------------------------------
10
15
 
11
- # ---------------------------------------------------------------------
16
+ class MySubject
17
+ include Mongoid::Document
18
+ include MongoidAbility::Subject
12
19
 
13
- class TestOwnerSuper
14
- include Mongoid::Document
15
- include MongoidAbility::Owner
20
+ default_lock MyLock, :read, true
21
+ default_lock MyLock1, :update, false
22
+ end
16
23
 
17
- embeds_many :test_locks, class_name: 'TestLock', as: :owner
18
- end
24
+ class MySubject1 < MySubject
25
+ default_lock MyLock, :read, false
26
+ end
19
27
 
20
- class TestOwner < TestOwnerSuper
21
- end
28
+ class MySubject2 < MySubject1
29
+ end
22
30
 
23
- # ---------------------------------------------------------------------
31
+ # ---------------------------------------------------------------------
24
32
 
25
- class SubjectTest
26
- include Mongoid::Document
27
- include MongoidAbility::Subject
33
+ class MyOwner
34
+ include Mongoid::Document
35
+ include MongoidAbility::Owner
28
36
 
29
- default_lock :read, true
30
- end
37
+ embeds_many :my_locks, class_name: 'MongoidAbility::MyLock', as: :owner
38
+ has_and_belongs_to_many :my_roles
31
39
 
32
- class SubjectTestOne < SubjectTest
33
- end
40
+ def self.locks_relation_name
41
+ :my_locks
42
+ end
34
43
 
35
- class SubjectTestTwo < SubjectTest
36
- end
44
+ def self.inherit_from_relation_name
45
+ :my_roles
46
+ end
47
+ end
37
48
 
38
- class SubjectSingleTest
39
- include Mongoid::Document
40
- include MongoidAbility::Subject
49
+ class MyOwner1 < MyOwner
50
+ end
41
51
 
42
- default_lock :read, true
43
- end
52
+ # ---------------------------------------------------------------------
44
53
 
45
- # ---------------------------------------------------------------------
54
+ class MyRole
55
+ include Mongoid::Document
56
+ include MongoidAbility::Owner
46
57
 
47
- class TestAbilityResolverSubject
48
- include Mongoid::Document
49
- include MongoidAbility::Subject
58
+ embeds_many :my_locks, class_name: 'MongoidAbility::MyLock', as: :owner
59
+ has_and_belongs_to_many :my_owners
50
60
 
51
- default_lock :read, true
52
- end
53
-
54
- class TestAbilitySubjectSuper2
55
- include Mongoid::Document
56
- include MongoidAbility::Subject
61
+ def self.locks_relation_name
62
+ :my_locks
63
+ end
64
+ end
57
65
 
58
- default_lock :read, false
59
- default_lock :update, true
66
+ class MyRole1 < MyRole
67
+ end
60
68
  end
61
69
 
62
- class TestAbilitySubjectSuper1 < TestAbilitySubjectSuper2
63
- end
64
70
 
65
- class TestAbilitySubject < TestAbilitySubjectSuper1
66
- end
67
71
 
68
- # ---------------------------------------------------------------------
69
72
 
70
- class TestRole
71
- include Mongoid::Document
72
- include MongoidAbility::Owner
73
73
 
74
- field :name, type: String
75
74
 
76
- embeds_many :test_locks, class_name: 'TestLock', as: :owner
77
- has_and_belongs_to_many :users, class_name: 'TestUser'
78
- end
79
-
80
- class TestUser
81
- include Mongoid::Document
82
- include MongoidAbility::Owner
83
75
 
84
- embeds_many :test_locks, class_name: 'TestLock', as: :owner
85
- has_and_belongs_to_many :roles, class_name: 'TestRole'
86
- end
76
+ # class TestLock
77
+ # include Mongoid::Document
78
+ # include MongoidAbility::Lock
79
+ #
80
+ # embedded_in :owner, polymorphic: true
81
+ # end
82
+ #
83
+ # class TestLockSub < TestLock
84
+ # end
85
+ #
86
+ # # ---------------------------------------------------------------------
87
+ #
88
+ # class TestOwnerSuper
89
+ # include Mongoid::Document
90
+ # include MongoidAbility::Owner
91
+ #
92
+ # embeds_many :test_locks, class_name: 'TestLock', as: :owner
93
+ # end
94
+ #
95
+ # class TestOwner < TestOwnerSuper
96
+ # end
97
+ #
98
+ # # ---------------------------------------------------------------------
99
+ #
100
+ # class SubjectTest
101
+ # include Mongoid::Document
102
+ # include MongoidAbility::Subject
103
+ #
104
+ # default_lock :read, true
105
+ # end
106
+ #
107
+ # class SubjectTestOne < SubjectTest
108
+ # end
109
+ #
110
+ # class SubjectTestTwo < SubjectTest
111
+ # end
112
+ #
113
+ # class SubjectSingleTest
114
+ # include Mongoid::Document
115
+ # include MongoidAbility::Subject
116
+ #
117
+ # default_lock :read, true
118
+ # end
119
+ #
120
+ # # ---------------------------------------------------------------------
121
+ #
122
+ # class TestAbilityResolverSubject
123
+ # include Mongoid::Document
124
+ # include MongoidAbility::Subject
125
+ #
126
+ # default_lock :read, true
127
+ # end
128
+ #
129
+ # class TestAbilitySubjectSuper2
130
+ # include Mongoid::Document
131
+ # include MongoidAbility::Subject
132
+ #
133
+ # default_lock :read, false
134
+ # default_lock :update, true
135
+ # end
136
+ #
137
+ # class TestAbilitySubjectSuper1 < TestAbilitySubjectSuper2
138
+ # end
139
+ #
140
+ # class TestAbilitySubject < TestAbilitySubjectSuper1
141
+ # end
142
+ #
143
+ # # ---------------------------------------------------------------------
144
+ #
145
+ # class TestRole
146
+ # include Mongoid::Document
147
+ # include MongoidAbility::Owner
148
+ #
149
+ # field :name, type: String
150
+ #
151
+ # embeds_many :test_locks, class_name: 'TestLock', as: :owner
152
+ # has_and_belongs_to_many :users, class_name: 'TestUser'
153
+ # end
154
+ #
155
+ # class TestUser
156
+ # include Mongoid::Document
157
+ # include MongoidAbility::Owner
158
+ #
159
+ # embeds_many :test_locks, class_name: 'TestLock', as: :owner
160
+ # has_and_belongs_to_many :roles, class_name: 'TestRole'
161
+ # end