patriarch 0.2.2 → 0.2.3
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.
- data/.gitignore +1 -1
- data/lib/generators/patriarch/templates/authorization_service.rb +3 -4
- data/lib/patriarch/authorization_service.rb +48 -2
- data/lib/patriarch/behaviours.rb +254 -214
- data/lib/patriarch/dao_services/bipartite_relationship_builder_service.rb +3 -0
- data/lib/patriarch/tool_services/redis_cleaner_service.rb +13 -13
- data/lib/patriarch/tool_services/redis_extractor_service.rb +4 -4
- data/lib/patriarch/transaction.rb +8 -1
- data/lib/patriarch/version.rb +1 -1
- data/patriarch.gemspec +2 -2
- data/spec/lib/patriarch/behaviours_spec.rb +97 -10
- data/spec/lib/patriarch/destroy_entity_spec.rb +1 -24
- data/spec/lib/patriarch/tool_services/redis_cleaner_service_spec.rb +12 -11
- data/spec/spec_helper.rb +7 -18
- metadata +25 -14
data/.gitignore
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
class Patriarch::Services::<%= class_name %>::AuthorizationService < Patriarch::AuthorizationService
|
2
|
-
def grant?(
|
3
|
-
|
4
|
-
true
|
1
|
+
class Patriarch::Services::<%= class_name %>::AuthorizationService < Patriarch::AuthorizationService
|
2
|
+
def grant?(transac)
|
3
|
+
super
|
5
4
|
end
|
6
5
|
end
|
@@ -5,8 +5,54 @@ module Patriarch
|
|
5
5
|
include Singleton
|
6
6
|
|
7
7
|
# override if necessary
|
8
|
-
def grant?(
|
9
|
-
|
8
|
+
def grant?(transac)
|
9
|
+
# Insert authorization logic here ...
|
10
|
+
if verify_types(transac)
|
11
|
+
true
|
12
|
+
else
|
13
|
+
raise "that behaviour is not authorized"
|
14
|
+
end
|
15
|
+
#true
|
16
|
+
end
|
17
|
+
|
18
|
+
def verify_types(transac)
|
19
|
+
actor_model = transac.actor.class
|
20
|
+
actor_model_sym = actor_model.name.underscore.to_sym
|
21
|
+
|
22
|
+
target_model = transac.target.class
|
23
|
+
target_model_sym = target_model.name.underscore.to_sym
|
24
|
+
|
25
|
+
medium_model = transac.medium.class
|
26
|
+
medium_model_sym = medium_model.name.underscore.to_sym
|
27
|
+
|
28
|
+
behaviour = transac.relation_type.to_s.sub(/undo_/,'').underscore.to_sym
|
29
|
+
auths = []
|
30
|
+
|
31
|
+
if transac.tripartite?
|
32
|
+
# Verif for actor
|
33
|
+
auths << actor_model.patriarch_behaviours[behaviour][:on].map{ |b_sym| b_sym.to_s.underscore.to_sym }.include?(target_model_sym)
|
34
|
+
auths << actor_model.patriarch_behaviours[behaviour][:via].map{ |b_sym| b_sym.to_s.underscore.to_sym }.include?(medium_model_sym)
|
35
|
+
|
36
|
+
# Verif for target
|
37
|
+
auths << target_model.patriarch_behaviours[behaviour][:by].map{ |b_sym| b_sym.to_s.underscore.to_sym }.include?(actor_model_sym)
|
38
|
+
auths << target_model.patriarch_behaviours[behaviour][:via].map{ |b_sym| b_sym.to_s.underscore.to_sym }.include?(medium_model_sym)
|
39
|
+
|
40
|
+
# Verif for medium
|
41
|
+
auths << medium_model.patriarch_behaviours[behaviour][:medium_between].map{ |dual_sym_tab| dual_sym_tab.map{ |b_sym| b_sym.to_s.underscore.to_sym } }.include?(
|
42
|
+
[actor_model_sym, target_model_sym]
|
43
|
+
)
|
44
|
+
# cas particulier
|
45
|
+
else
|
46
|
+
auths << actor_model.patriarch_behaviours[behaviour][:on].map{ |b_sym| b_sym.to_s.underscore.to_sym }.include?(target_model_sym)
|
47
|
+
auths << target_model.patriarch_behaviours[behaviour][:by].map{ |b_sym| b_sym.to_s.underscore.to_sym }.include?(actor_model_sym)
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
if auths.include? false
|
52
|
+
false
|
53
|
+
else
|
54
|
+
true
|
55
|
+
end
|
10
56
|
end
|
11
57
|
end
|
12
58
|
end
|
data/lib/patriarch/behaviours.rb
CHANGED
@@ -36,16 +36,16 @@ module Patriarch
|
|
36
36
|
Patriarch::ToolServices::RedisExtractorService.instance.
|
37
37
|
get_models_from_ids(self,acted_on_model.to_s.classify.constantize,raw_tool_method_name,options)
|
38
38
|
end
|
39
|
-
if options[:
|
40
|
-
alias_for_classic = classic_tool_method_name.sub(relation_type.to_s, options[:
|
39
|
+
if options[:as]
|
40
|
+
alias_for_classic = classic_tool_method_name.sub(relation_type.to_s, options[:as].to_s)
|
41
41
|
alias_method alias_for_classic, classic_tool_method_name
|
42
42
|
end
|
43
43
|
|
44
44
|
define_method(raw_tool_method_name) do |options={}|
|
45
45
|
Patriarch::ToolServices::RedisExtractorService.instance.get_ids_from_sorted_set(self,redis_key,options)
|
46
46
|
end
|
47
|
-
if options[:
|
48
|
-
alias_for_raw = raw_tool_method_name.sub(relation_type.to_s, options[:
|
47
|
+
if options[:as]
|
48
|
+
alias_for_raw = raw_tool_method_name.sub(relation_type.to_s, options[:as].to_s)
|
49
49
|
alias_method alias_for_raw, raw_tool_method_name
|
50
50
|
end
|
51
51
|
end
|
@@ -69,8 +69,8 @@ module Patriarch
|
|
69
69
|
Patriarch::ToolServices::RedisExtractorService.instance.
|
70
70
|
get_models_from_ids(self,targetted_by_model.to_s.classify.constantize,raw_tool_method_name,options)
|
71
71
|
end
|
72
|
-
if options[:
|
73
|
-
progressive_present_relation_type_alias = (Verbs::Conjugator.conjugate options[:
|
72
|
+
if options[:as]
|
73
|
+
progressive_present_relation_type_alias = (Verbs::Conjugator.conjugate options[:as], :aspect => :progressive).split(/ /).last
|
74
74
|
alias_for_classic = classic_tool_method_name.sub(progressive_present_relation_type,progressive_present_relation_type_alias)
|
75
75
|
alias_method alias_for_classic, classic_tool_method_name
|
76
76
|
end
|
@@ -78,8 +78,8 @@ module Patriarch
|
|
78
78
|
define_method(raw_tool_method_name) do |options={}|
|
79
79
|
Patriarch::ToolServices::RedisExtractorService.instance.get_ids_from_sorted_set(self,redis_key,options)
|
80
80
|
end
|
81
|
-
if options[:
|
82
|
-
progressive_present_relation_type_alias = (Verbs::Conjugator.conjugate options[:
|
81
|
+
if options[:as]
|
82
|
+
progressive_present_relation_type_alias = (Verbs::Conjugator.conjugate options[:as], :aspect => :progressive).split(/ /).last
|
83
83
|
alias_for_raw = raw_tool_method_name.sub(progressive_present_relation_type,progressive_present_relation_type_alias)
|
84
84
|
alias_method alias_for_raw, raw_tool_method_name
|
85
85
|
end
|
@@ -89,7 +89,6 @@ module Patriarch
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
|
-
|
93
92
|
def complete_custom_active_module_tripartite(module_to_complete,relation_type,acted_on_model_list,via_model_list,options={})
|
94
93
|
module_to_complete.class_eval do
|
95
94
|
|
@@ -97,31 +96,54 @@ module Patriarch
|
|
97
96
|
via_model_list.each do |via_model|
|
98
97
|
|
99
98
|
# Compute names based on conventions
|
100
|
-
|
101
|
-
|
102
|
-
|
99
|
+
# fallen_angels_i_praise_via_love_letters
|
100
|
+
target_classic_tool_method_name = "#{acted_on_model.to_s.tableize}_i_#{relation_type.to_s}_via_#{via_model.to_s.tableize}"
|
101
|
+
target_raw_tool_method_name = target_classic_tool_method_name + "_ids"
|
102
|
+
|
103
|
+
# love_letters_i_use_to_praise_fallen_angels
|
104
|
+
medium_classic_tool_method_name = "#{via_model.to_s.tableize}_i_use_to_#{relation_type.to_s}_#{acted_on_model.to_s.tableize}"
|
105
|
+
medium_raw_tool_method_name = medium_classic_tool_method_name + "_ids"
|
106
|
+
|
107
|
+
redis_key = "patriarch_" + target_classic_tool_method_name
|
103
108
|
|
104
109
|
# Define methods with the pattern : items_i_like that returns models and items_i_like_ids that return
|
105
110
|
# Redis key has the same radical as the method in class by convention (but has a patriarch_ prefix to avoid collisions with other gems)
|
106
|
-
define_method(
|
111
|
+
define_method(target_classic_tool_method_name) do |options={}|
|
107
112
|
Patriarch::ToolServices::RedisExtractorService.instance.
|
108
|
-
get_models_from_ids(self,acted_on_model.to_s.classify.constantize,
|
113
|
+
get_models_from_ids(self,acted_on_model.to_s.classify.constantize,target_raw_tool_method_name,options.merge({:tripartite => true}))
|
109
114
|
end
|
110
|
-
if options[:
|
111
|
-
alias_for_classic =
|
112
|
-
alias_method alias_for_classic,
|
115
|
+
if options[:as]
|
116
|
+
alias_for_classic = target_classic_tool_method_name.sub(relation_type.to_s, options[:as].to_s)
|
117
|
+
alias_method alias_for_classic, target_classic_tool_method_name
|
113
118
|
end
|
114
119
|
|
115
|
-
define_method(
|
116
|
-
Patriarch::ToolServices::RedisExtractorService.instance.get_ids_from_sorted_set(self,redis_key,options.merge({:tripartite => true, :protagonist_type => :
|
117
|
-
# triplet is by convention [actor,target,medium]
|
118
|
-
# TODO Marshallize true items instead of some crappy convention ...
|
120
|
+
define_method(target_raw_tool_method_name) do |options={}|
|
121
|
+
Patriarch::ToolServices::RedisExtractorService.instance.get_ids_from_sorted_set(self,redis_key,options.merge({:tripartite => true, :protagonist_type => :target}))
|
119
122
|
end
|
120
|
-
if options[:
|
121
|
-
|
122
|
-
alias_method
|
123
|
+
if options[:as]
|
124
|
+
alias_for_target_raw = target_raw_tool_method_name.sub(relation_type.to_s, options[:as].to_s)
|
125
|
+
alias_method alias_for_target_raw, target_raw_tool_method_name
|
123
126
|
end
|
124
127
|
|
128
|
+
#
|
129
|
+
define_method(medium_classic_tool_method_name) do |options={}|
|
130
|
+
Patriarch::ToolServices::RedisExtractorService.instance.
|
131
|
+
get_models_from_ids(self,via_model.to_s.classify.constantize,medium_raw_tool_method_name,options.merge({:tripartite => true}))
|
132
|
+
end
|
133
|
+
if options[:as]
|
134
|
+
alias_for_medium_classic = medium_classic_tool_method_name.sub(relation_type.to_s, options[:as].to_s)
|
135
|
+
alias_method alias_for_medium_classic, medium_classic_tool_method_name
|
136
|
+
end
|
137
|
+
#
|
138
|
+
|
139
|
+
define_method(medium_raw_tool_method_name) do |options={}|
|
140
|
+
Patriarch::ToolServices::RedisExtractorService.instance.get_ids_from_sorted_set(self,redis_key,options.merge({:tripartite => true, :protagonist_type => :medium}))
|
141
|
+
end
|
142
|
+
if options[:as]
|
143
|
+
alias_for_medium_raw = medium_raw_tool_method_name.sub(relation_type.to_s, options[:as].to_s)
|
144
|
+
alias_method alias_for_medium_raw, medium_raw_tool_method_name
|
145
|
+
end
|
146
|
+
|
125
147
|
end
|
126
148
|
end
|
127
149
|
|
@@ -135,35 +157,45 @@ module Patriarch
|
|
135
157
|
via_model_list.each do |via_model|
|
136
158
|
# Compute names based on conventions
|
137
159
|
progressive_present_relation_type = (Verbs::Conjugator.conjugate relation_type.to_sym, :aspect => :progressive).split(/ /).last
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
#
|
143
|
-
|
144
|
-
|
160
|
+
|
161
|
+
actor_classic_tool_method_name = "#{targetted_by_model.to_s.tableize}_#{progressive_present_relation_type}_me_via_#{via_model.to_s.tableize}"
|
162
|
+
actor_raw_tool_method_name = actor_classic_tool_method_name + "_ids"
|
163
|
+
|
164
|
+
#"love_letters_used_by_monsters_to_praise_me"
|
165
|
+
medium_classic_tool_method_name = "#{via_model.to_s.tableize}_used_by_#{targetted_by_model.to_s.tableize}_to_#{relation_type.to_s}_me"
|
166
|
+
medium_raw_tool_method_name = medium_classic_tool_method_name + "_ids"
|
167
|
+
|
168
|
+
redis_key = "patriarch_" + actor_classic_tool_method_name
|
169
|
+
|
170
|
+
define_method(actor_classic_tool_method_name) do |options={}|
|
145
171
|
Patriarch::ToolServices::RedisExtractorService.instance.
|
146
|
-
get_models_from_ids(self,targetted_by_model.to_s.classify.constantize,
|
172
|
+
get_models_from_ids(self,targetted_by_model.to_s.classify.constantize,actor_raw_tool_method_name,options.merge({:tripartite => true}))
|
147
173
|
end
|
148
|
-
if options[:
|
149
|
-
progressive_present_relation_type_alias = (Verbs::Conjugator.conjugate options[:
|
150
|
-
|
151
|
-
alias_method
|
174
|
+
if options[:as]
|
175
|
+
progressive_present_relation_type_alias = (Verbs::Conjugator.conjugate options[:as], :aspect => :progressive).split(/ /).last
|
176
|
+
alias_for_actor_classic = actor_classic_tool_method_name.sub(progressive_present_relation_type,progressive_present_relation_type_alias)
|
177
|
+
alias_method alias_for_actor_classic, actor_classic_tool_method_name
|
152
178
|
end
|
153
179
|
|
154
|
-
|
155
|
-
|
156
|
-
Patriarch::ToolServices::RedisExtractorService.instance.get_ids_from_sorted_set(self,redis_key,options.merge({:tripartite => true , :protagonist_type => :target}))
|
157
|
-
|
158
|
-
# triplet is by convention [actor,target,medium]
|
159
|
-
# TODO Marshallize true items instead of some crappy convention ...
|
180
|
+
define_method(actor_raw_tool_method_name) do |options={}|
|
181
|
+
Patriarch::ToolServices::RedisExtractorService.instance.get_ids_from_sorted_set(self,redis_key,options.merge({:tripartite => true , :protagonist_type => :actor}))
|
160
182
|
end
|
161
|
-
if options[:
|
162
|
-
progressive_present_relation_type_alias = (Verbs::Conjugator.conjugate options[:
|
163
|
-
|
164
|
-
alias_method
|
183
|
+
if options[:as]
|
184
|
+
progressive_present_relation_type_alias = (Verbs::Conjugator.conjugate options[:as], :aspect => :progressive).split(/ /).last
|
185
|
+
alias_for_actor_raw = actor_raw_tool_method_name.sub(progressive_present_relation_type,progressive_present_relation_type_alias)
|
186
|
+
alias_method alias_for_actor_raw, actor_raw_tool_method_name
|
165
187
|
end
|
166
188
|
|
189
|
+
define_method(medium_classic_tool_method_name) do |options={}|
|
190
|
+
Patriarch::ToolServices::RedisExtractorService.instance.
|
191
|
+
get_models_from_ids(self,via_model.to_s.classify.constantize,medium_raw_tool_method_name,options.merge({:tripartite => true}))
|
192
|
+
end
|
193
|
+
#TODO add alias there
|
194
|
+
# FIXME id in it is wrong ...
|
195
|
+
define_method(medium_raw_tool_method_name) do |options={}|
|
196
|
+
Patriarch::ToolServices::RedisExtractorService.instance.get_ids_from_sorted_set(self,redis_key,options.merge({:tripartite => true , :protagonist_type => :medium}))
|
197
|
+
end
|
198
|
+
|
167
199
|
end
|
168
200
|
end
|
169
201
|
|
@@ -210,19 +242,29 @@ module Patriarch
|
|
210
242
|
|
211
243
|
module ClassMethods
|
212
244
|
|
213
|
-
def
|
245
|
+
def check_add_behaviour_syntax(behaviour,options)
|
214
246
|
if options[:medium_between] || options[:via]
|
215
|
-
|
247
|
+
check_tripartite_add_behaviour_syntax(behaviour,options)
|
216
248
|
elsif options[:on] || options[:by]
|
217
|
-
|
218
|
-
else
|
219
|
-
raise AddBehaviourSyntaxError, "syntax is wrong, declaration does not suplly enough arguments declared with right options"
|
249
|
+
check_bipartite_add_behaviour_syntax(behaviour,options)
|
220
250
|
end
|
221
251
|
end
|
222
252
|
|
223
|
-
def
|
224
|
-
behaviour
|
253
|
+
def check_bipartite_add_behaviour_syntax(behaviour,options)
|
254
|
+
# Either you add a behaviour on another model or allow a behaviour on you by another model
|
255
|
+
unless options[:by].nil? ^ options[:on].nil?
|
256
|
+
raise AddBehaviourSyntaxError, "you must not define a behaviour as active (using on) and passive at the same time (using by)"
|
257
|
+
end
|
258
|
+
|
259
|
+
# as option should be a string or symbol
|
260
|
+
if options[:as]
|
261
|
+
unless [Symbol,String].include?(options[:as].class)
|
262
|
+
raise AddBehaviourSyntaxError, "as option should be a string or symbol"
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
225
266
|
|
267
|
+
def check_tripartite_add_behaviour_syntax(behaviour,options)
|
226
268
|
# Xor on options :medium_between and :via, disparate cases ...
|
227
269
|
unless options[:medium_between].nil? ^ options[:via].nil?
|
228
270
|
raise AddBehaviourSyntaxError, "you must not define a behaviour as active (using on) and passive at the same time (using by)"
|
@@ -239,222 +281,220 @@ module Patriarch
|
|
239
281
|
end
|
240
282
|
end
|
241
283
|
|
242
|
-
complete_module_options = {}
|
243
284
|
if options[:as]
|
244
285
|
# as option should be a string or symbol
|
245
286
|
unless [Symbol,String].include?(options[:as].class)
|
246
287
|
raise AddBehaviourSyntaxError, "as option should be a string or symbol"
|
247
288
|
end
|
248
|
-
complete_module_options.merge! :relation_type_alias => options[:as]
|
249
289
|
end
|
290
|
+
end
|
250
291
|
|
251
|
-
|
252
|
-
|
292
|
+
def add_behaviour(behaviour,options)
|
293
|
+
if options[:medium_between] || options[:via]
|
294
|
+
add_tripartite_behaviour(behaviour,options)
|
295
|
+
elsif options[:on] || options[:by]
|
296
|
+
add_bipartite_behaviour(behaviour,options)
|
297
|
+
else
|
298
|
+
raise AddBehaviourSyntaxError, "syntax is wrong, declaration does not suplly enough arguments declared with right options"
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
def add_aliases_for_functionnalities(module_to_complete,behaviour,options)
|
253
303
|
if options[:as]
|
254
|
-
|
255
|
-
end
|
304
|
+
behaviour_alias = options[:as].to_s
|
305
|
+
end
|
256
306
|
|
257
307
|
if options[:undo_as]
|
258
|
-
|
259
|
-
end
|
308
|
+
behaviour_undo_alias = options[:undo_as].to_s
|
309
|
+
end
|
310
|
+
|
311
|
+
if options[:on]
|
312
|
+
module_to_complete.instance_eval do
|
313
|
+
# add behaviour_alias
|
314
|
+
if options[:as]
|
315
|
+
alias_method behaviour_alias, behaviour
|
316
|
+
end
|
260
317
|
|
318
|
+
# add undo_behaviour_alias
|
319
|
+
if options[:undo_as]
|
320
|
+
alias_method behaviour_undo_alias, Patriarch.undo(behaviour)
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
261
325
|
|
262
|
-
|
263
|
-
|
264
|
-
# Actor case
|
265
|
-
if options[:on]
|
266
|
-
methods_mod.instance_eval do
|
267
|
-
# Defines the hook thing ...
|
268
|
-
# TODO
|
269
|
-
def self.included(klass)
|
270
|
-
klass.extend ActiveModel::Callbacks
|
271
|
-
klass.send(:define_model_callbacks, self.const_get(:Behaviour).to_sym, Patriarch.undo(self.const_get(:Behaviour)).to_sym)
|
272
|
-
end
|
326
|
+
def add_functionnalities_for_bipartite(module_to_complete,behaviour,options)
|
327
|
+
module_to_complete.instance_eval do
|
273
328
|
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
if options[:as]
|
281
|
-
alias_method methods_mod.const_get(:BehaviourAlias), methods_mod.const_get(:Behaviour).to_sym
|
282
|
-
end
|
283
|
-
|
284
|
-
# undo_behave
|
285
|
-
define_method(Patriarch.undo(methods_mod.const_get(:Behaviour)).to_sym) do |entity,via_entity,options={}|
|
286
|
-
run_callbacks Patriarch.undo(methods_mod.const_get(:Behaviour)).to_sym do
|
287
|
-
"Patriarch::Services::#{(Patriarch.undo(methods_mod.const_get(:Behaviour))).classify}::ManagerService".constantize.instance.resolve(self,entity,via_entity,options)
|
288
|
-
end
|
289
|
-
end
|
290
|
-
if options[:undo_as]
|
291
|
-
alias_method methods_mod.const_get(:UndoBehaviourAlias), Patriarch.undo(methods_mod.const_get(:Behaviour))
|
292
|
-
end
|
329
|
+
instance_eval do
|
330
|
+
(class << self; self; end).send(:define_method,:included) do |klass|
|
331
|
+
klass.extend ActiveModel::Callbacks
|
332
|
+
klass.send(:define_model_callbacks, behaviour, Patriarch.undo(behaviour))
|
333
|
+
end
|
334
|
+
end
|
293
335
|
|
336
|
+
# behave
|
337
|
+
define_method(behaviour) do |entity,options={}|
|
338
|
+
run_callbacks behaviour do
|
339
|
+
"Patriarch::Services::#{behaviour.classify}::ManagerService".constantize.instance.resolve(self,entity,options)
|
294
340
|
end
|
341
|
+
end
|
295
342
|
|
296
|
-
|
297
|
-
|
298
|
-
Patriarch
|
299
|
-
|
300
|
-
|
301
|
-
targetted_by_model_list = Array(options[:by])
|
302
|
-
via_model_list = Array(options[:via])
|
303
|
-
Patriarch::Behaviours.complete_custom_passive_module_tripartite(methods_mod,behaviour,targetted_by_model_list,via_model_list,complete_module_options)
|
343
|
+
# undo_behave
|
344
|
+
define_method(Patriarch.undo(behaviour).to_sym) do |entity,options={}|
|
345
|
+
run_callbacks Patriarch.undo(behaviour).to_sym do
|
346
|
+
"Patriarch::Services::#{(Patriarch.undo(behaviour)).classify}::ManagerService".constantize.instance.resolve(self,entity,options)
|
347
|
+
end
|
304
348
|
end
|
305
|
-
# Medium case
|
306
|
-
elsif options[:medium_between]
|
307
|
-
# Define tool_methods_here ...
|
308
|
-
end
|
309
349
|
|
310
|
-
#
|
311
|
-
|
312
|
-
|
313
|
-
|
350
|
+
end # instance_eval
|
351
|
+
end
|
352
|
+
|
353
|
+
def add_functionnalities_for_tripartite(module_to_complete,behaviour,options)
|
354
|
+
module_to_complete.instance_eval do
|
355
|
+
|
356
|
+
instance_eval do
|
357
|
+
(class << self; self; end).send(:define_method,:included) do |klass|
|
358
|
+
klass.extend ActiveModel::Callbacks
|
359
|
+
klass.send(:define_model_callbacks, behaviour, Patriarch.undo(behaviour))
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
# behave
|
364
|
+
define_method(behaviour) do |via_entity,entity,options={}|
|
365
|
+
run_callbacks behaviour.to_sym do
|
366
|
+
"Patriarch::Services::#{behaviour.classify}::ManagerService".constantize.instance.resolve(self,entity,via_entity,options)
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
|
371
|
+
# undo_behave
|
372
|
+
define_method(Patriarch.undo(behaviour)) do |via_entity,entity,options={}|
|
373
|
+
run_callbacks Patriarch.undo(behaviour).to_sym do
|
374
|
+
"Patriarch::Services::#{Patriarch.undo(behaviour).classify}::ManagerService".constantize.instance.resolve(self,entity,via_entity,options)
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
end # instance_eval
|
379
|
+
end
|
380
|
+
|
381
|
+
def register_bipartite_behaviour(behaviour,options)
|
382
|
+
self.patriarch_behaviours ||= { }
|
383
|
+
#self.patriarch_behaviours[behaviour.underscore.to_sym] ||= { :on => [], :by =>[] }
|
384
|
+
self.patriarch_behaviours[behaviour.underscore.to_sym] ||= { }
|
385
|
+
self.patriarch_behaviours[behaviour.underscore.to_sym][:on] ||= []
|
386
|
+
self.patriarch_behaviours[behaviour.underscore.to_sym][:by] ||= []
|
387
|
+
|
388
|
+
if options[:on]
|
389
|
+
self.patriarch_behaviours[behaviour.underscore.to_sym][:on] << options[:on]
|
390
|
+
self.patriarch_behaviours[behaviour.underscore.to_sym][:on].uniq!
|
391
|
+
self.patriarch_behaviours[behaviour.underscore.to_sym][:on].flatten!
|
392
|
+
elsif options[:by]
|
393
|
+
self.patriarch_behaviours[behaviour.underscore.to_sym][:by] << options[:by]
|
394
|
+
self.patriarch_behaviours[behaviour.underscore.to_sym][:by].uniq!
|
395
|
+
self.patriarch_behaviours[behaviour.underscore.to_sym][:by].flatten!
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
def register_tripartite_behaviour(behaviour,options)
|
314
400
|
# TODO disjonction register tripartite
|
315
401
|
# register the behaviour we just added
|
402
|
+
behaviour = behaviour.underscore.to_sym
|
403
|
+
|
316
404
|
self.patriarch_behaviours ||= { }
|
317
|
-
self.patriarch_behaviours[behaviour
|
405
|
+
self.patriarch_behaviours[behaviour] ||= {}
|
318
406
|
|
319
407
|
if options[:via]
|
320
408
|
#self.patriarch_behaviours[behaviour.underscore.to_sym] ||= { :on => [], :by => [], :via => [] }
|
321
|
-
self.patriarch_behaviours[behaviour
|
322
|
-
self.patriarch_behaviours[behaviour
|
323
|
-
self.patriarch_behaviours[behaviour
|
409
|
+
self.patriarch_behaviours[behaviour][:on] ||= []
|
410
|
+
self.patriarch_behaviours[behaviour][:by] ||= []
|
411
|
+
self.patriarch_behaviours[behaviour][:via] ||= []
|
324
412
|
elsif options[:medium_between]
|
325
413
|
#self.patriarch_behaviours[behaviour.underscore.to_sym] ||= { :medium_between => [] }
|
326
|
-
self.patriarch_behaviours[behaviour
|
414
|
+
self.patriarch_behaviours[behaviour][:medium_between] ||= []
|
327
415
|
end
|
328
416
|
|
329
417
|
if options[:via]
|
330
418
|
if options[:on]
|
331
|
-
self.patriarch_behaviours[behaviour
|
332
|
-
self.patriarch_behaviours[behaviour
|
333
|
-
self.patriarch_behaviours[behaviour
|
419
|
+
self.patriarch_behaviours[behaviour][:on] << options[:on]
|
420
|
+
self.patriarch_behaviours[behaviour][:on].uniq!
|
421
|
+
self.patriarch_behaviours[behaviour][:on].flatten!
|
334
422
|
elsif options[:by]
|
335
|
-
self.patriarch_behaviours[behaviour
|
336
|
-
self.patriarch_behaviours[behaviour
|
337
|
-
self.patriarch_behaviours[behaviour
|
423
|
+
self.patriarch_behaviours[behaviour][:by] << options[:by]
|
424
|
+
self.patriarch_behaviours[behaviour][:by].uniq!
|
425
|
+
self.patriarch_behaviours[behaviour][:by].flatten!
|
338
426
|
end
|
339
|
-
self.patriarch_behaviours[behaviour
|
340
|
-
self.patriarch_behaviours[behaviour
|
341
|
-
self.patriarch_behaviours[behaviour
|
427
|
+
self.patriarch_behaviours[behaviour][:via] << options[:via]
|
428
|
+
self.patriarch_behaviours[behaviour][:via].uniq!
|
429
|
+
self.patriarch_behaviours[behaviour][:via].flatten!
|
342
430
|
elsif options[:medium_between]
|
343
|
-
self.patriarch_behaviours[behaviour
|
344
|
-
self.patriarch_behaviours[behaviour
|
345
|
-
self.patriarch_behaviours[behaviour
|
431
|
+
self.patriarch_behaviours[behaviour][:medium_between] << options[:medium_between]
|
432
|
+
self.patriarch_behaviours[behaviour][:medium_between].uniq!
|
433
|
+
self.patriarch_behaviours[behaviour][:medium_between]
|
346
434
|
end
|
347
435
|
end
|
348
436
|
|
349
|
-
def
|
350
|
-
# add_behaviour :like, :by => bla, :on => [:item,:user] || :community, :as => :aimer, :reverse_as => :haïr ...
|
351
|
-
|
437
|
+
def add_tripartite_behaviour(behaviour,options)
|
352
438
|
behaviour = behaviour.to_s.underscore
|
353
439
|
|
354
|
-
|
355
|
-
unless options[:by].nil? ^ options[:on].nil?
|
356
|
-
raise AddBehaviourSyntaxError, "you must not define a behaviour as active (using on) and passive at the same time (using by)"
|
357
|
-
end
|
440
|
+
check_add_behaviour_syntax(behaviour,options)
|
358
441
|
|
359
442
|
methods_mod = Module.new do; end
|
360
|
-
methods_mod.const_set(:Behaviour,behaviour)
|
361
|
-
if options[:as]
|
362
|
-
methods_mod.const_set(:BehaviourAlias,options[:as].to_sym)
|
363
|
-
end
|
364
|
-
if options[:undo_as]
|
365
|
-
methods_mod.const_set(:UndoBehaviourAlias,options[:undo_as].to_sym)
|
366
|
-
end
|
367
|
-
|
368
|
-
if options[:on]
|
369
|
-
# Adds active methods and defines the hook to set callbacks on them
|
370
|
-
methods_mod.instance_eval do
|
371
|
-
|
372
|
-
# Defines the hook thing ...
|
373
|
-
# TODO
|
374
|
-
def self.included(klass)
|
375
|
-
klass.extend ActiveModel::Callbacks
|
376
|
-
klass.send(:define_model_callbacks, self.const_get(:Behaviour).to_sym, Patriarch.undo(self.const_get(:Behaviour)).to_sym)
|
377
|
-
end
|
378
443
|
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
end
|
394
|
-
end
|
395
|
-
if options[:undo_as]
|
396
|
-
alias_method methods_mod.const_get(:UndoBehaviourAlias), Patriarch.undo(methods_mod.const_get(:Behaviour))
|
397
|
-
end
|
398
|
-
|
399
|
-
# Not used / not tested, added this method "en passant"
|
400
|
-
# FIX requirements with users
|
401
|
-
# likes?
|
402
|
-
define_method((Verbs::Conjugator.conjugate methods_mod.const_get(:Behaviour).to_sym, :person => :third).split(/ /).last) do |entity|
|
403
|
-
self.send("#{entity.class.name.tableize}_i_#{methods_mod.const_get(:Behaviour)}_ids").include? entity.id
|
404
|
-
end
|
444
|
+
# Target on Actor cases
|
445
|
+
if options[:via]
|
446
|
+
# Actor case
|
447
|
+
if options[:on]
|
448
|
+
add_functionnalities_for_tripartite(methods_mod,behaviour,options)
|
449
|
+
add_aliases_for_functionnalities(methods_mod,behaviour,options)
|
450
|
+
acted_on_model_list = Array(options[:on])
|
451
|
+
via_model_list = Array(options[:via])
|
452
|
+
Patriarch::Behaviours.complete_custom_active_module_tripartite(methods_mod,behaviour,acted_on_model_list,via_model_list,options)
|
453
|
+
#Target case
|
454
|
+
elsif options[:by]
|
455
|
+
targetted_by_model_list = Array(options[:by])
|
456
|
+
via_model_list = Array(options[:via])
|
457
|
+
Patriarch::Behaviours.complete_custom_passive_module_tripartite(methods_mod,behaviour,targetted_by_model_list,via_model_list,options)
|
405
458
|
end
|
459
|
+
# Medium case
|
460
|
+
elsif options[:medium_between]
|
461
|
+
# Define tool_methods_here ...
|
406
462
|
end
|
407
463
|
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
#end
|
416
|
-
end
|
417
|
-
end
|
464
|
+
# Finally ...
|
465
|
+
include methods_mod
|
466
|
+
# include in which we can overwite the methods of the previous custom module included there ...
|
467
|
+
include "Patriarch::Behaviours::#{behaviour.classify}::ToolsMethods".constantize
|
468
|
+
# register behaviour we just added
|
469
|
+
register_tripartite_behaviour(behaviour,options)
|
470
|
+
end
|
418
471
|
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
complete_module_options.merge! :relation_type_alias => options[:as]
|
426
|
-
end
|
472
|
+
def add_bipartite_behaviour(behaviour,options)
|
473
|
+
# add_behaviour :like, :by => bla, :on => [:item,:user] || :community, :as => :aimer, :reverse_as => :haïr ...
|
474
|
+
|
475
|
+
behaviour = behaviour.to_s.underscore
|
476
|
+
|
477
|
+
check_add_behaviour_syntax(behaviour,options)
|
427
478
|
|
479
|
+
methods_mod = Module.new do; end
|
428
480
|
|
429
481
|
if options[:on]
|
482
|
+
# Adds active methods and defines the hook to set callbacks on them
|
483
|
+
add_functionnalities_for_bipartite(methods_mod,behaviour,options)
|
484
|
+
add_aliases_for_functionnalities(methods_mod,behaviour,options)
|
430
485
|
acted_on_model_list = Array(options[:on])
|
431
|
-
Patriarch::Behaviours.complete_custom_active_module_bipartite(methods_mod,behaviour,acted_on_model_list,
|
486
|
+
Patriarch::Behaviours.complete_custom_active_module_bipartite(methods_mod,behaviour,acted_on_model_list,options)
|
432
487
|
else
|
433
488
|
targetted_by_model_list = Array(options[:by])
|
434
|
-
Patriarch::Behaviours.complete_custom_passive_module_bipartite(methods_mod,behaviour,targetted_by_model_list,
|
489
|
+
Patriarch::Behaviours.complete_custom_passive_module_bipartite(methods_mod,behaviour,targetted_by_model_list,options)
|
435
490
|
end
|
436
491
|
|
437
|
-
# Finally
|
438
|
-
|
492
|
+
# Finally includes the custom module
|
493
|
+
include methods_mod
|
439
494
|
# include in which we can overwite the methods of the previous custom module included there ...
|
440
|
-
|
441
|
-
|
495
|
+
include "Patriarch::Behaviours::#{behaviour.classify}::ToolsMethods".constantize
|
442
496
|
# register the behaviour we just added
|
443
|
-
|
444
|
-
#self.patriarch_behaviours[behaviour.underscore.to_sym] ||= { :on => [], :by =>[] }
|
445
|
-
self.patriarch_behaviours[behaviour.underscore.to_sym] ||= { }
|
446
|
-
self.patriarch_behaviours[behaviour.underscore.to_sym][:on] ||= []
|
447
|
-
self.patriarch_behaviours[behaviour.underscore.to_sym][:by] ||= []
|
448
|
-
|
449
|
-
if options[:on]
|
450
|
-
self.patriarch_behaviours[behaviour.underscore.to_sym][:on] << options[:on]
|
451
|
-
self.patriarch_behaviours[behaviour.underscore.to_sym][:on].uniq!
|
452
|
-
self.patriarch_behaviours[behaviour.underscore.to_sym][:on].flatten!
|
453
|
-
elsif options[:by]
|
454
|
-
self.patriarch_behaviours[behaviour.underscore.to_sym][:by] << options[:by]
|
455
|
-
self.patriarch_behaviours[behaviour.underscore.to_sym][:by].uniq!
|
456
|
-
self.patriarch_behaviours[behaviour.underscore.to_sym][:by].flatten!
|
457
|
-
end
|
497
|
+
register_bipartite_behaviour(behaviour,options)
|
458
498
|
end
|
459
499
|
end
|
460
500
|
|
@@ -25,6 +25,9 @@ class Patriarch::DAOServices::BipartiteRelationshipBuilderService < Patriarch::S
|
|
25
25
|
l = lambda { actor_dao.delete transaction_item.target_id }
|
26
26
|
ll = lambda { target_dao.delete transaction_item.actor_id }
|
27
27
|
|
28
|
+
# p "#{l.inspect} is deleting on key #{actor_dao.key} : #{transaction_item.target_type} #{transaction_item.target_id}"
|
29
|
+
# p "#{ll.inspect} is deleting on key #{target_dao.key} : #{transaction_item.actor_type} #{transaction_item.actor_id}"
|
30
|
+
|
28
31
|
transaction_item.add_to_queue l
|
29
32
|
transaction_item.add_to_queue ll
|
30
33
|
end
|
@@ -6,7 +6,7 @@ class Patriarch::ToolServices::RedisCleanerService < Patriarch::Service
|
|
6
6
|
options = { :transac => transac }
|
7
7
|
|
8
8
|
calling_entity.class.patriarch_behaviours.keys.each do |behaviour|
|
9
|
-
clean_behaviour(calling_entity,behaviour
|
9
|
+
transac.steps << clean_behaviour(calling_entity,behaviour)
|
10
10
|
end
|
11
11
|
|
12
12
|
transac
|
@@ -47,7 +47,7 @@ class Patriarch::ToolServices::RedisCleanerService < Patriarch::Service
|
|
47
47
|
calling_entity.send("#{acted_on_model.to_s.tableize}_i_#{behaviour.to_s}_via_#{via_model.to_s.tableize}", :with_medium => true).each do |tripartite_hash|
|
48
48
|
target_i_behaved_on = Array(acted_on_model.to_s.classify.constantize.find(tripartite_hash[:target])).first
|
49
49
|
medium_for_behaviour = Array(via_model.to_s.classify.constantize.find(tripartite_hash[:medium])).first
|
50
|
-
calling_entity.send(Patriarch.undo(behaviour.to_s).underscore,target_i_behaved_on,
|
50
|
+
calling_entity.send(Patriarch.undo(behaviour.to_s).underscore,medium_for_behaviour,target_i_behaved_on,options)
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
@@ -64,7 +64,7 @@ class Patriarch::ToolServices::RedisCleanerService < Patriarch::Service
|
|
64
64
|
actor_that_behaved_on_me = Array(targetted_by_model.to_s.classify.constantize.find(tripartite_hash[:actor])).first
|
65
65
|
medium_for_behaviour = Array(via_model.to_s.classify.constantize.find(tripartite_hash[:medium])).first
|
66
66
|
#
|
67
|
-
actor_that_behaved_on_me.send(Patriarch.undo(behaviour.to_s).underscore,calling_entity,
|
67
|
+
actor_that_behaved_on_me.send(Patriarch.undo(behaviour.to_s).underscore,medium_for_behaviour,calling_entity,options)
|
68
68
|
end
|
69
69
|
end
|
70
70
|
end
|
@@ -92,7 +92,15 @@ class Patriarch::ToolServices::RedisCleanerService < Patriarch::Service
|
|
92
92
|
options = { :transac => transac, :stop_execution => true}
|
93
93
|
|
94
94
|
if my_behaviours.include? behaviour.to_s.underscore.to_sym
|
95
|
-
|
95
|
+
# Dealing with passive behaviour
|
96
|
+
if my_behaviours[behaviour.to_s.underscore.to_sym][:by]
|
97
|
+
targetted_by_models = my_behaviours[behaviour.to_s.underscore.to_sym][:by]
|
98
|
+
targetted_by_models.each do |targetted_by_model|
|
99
|
+
calling_entity.send("#{targetted_by_model.to_s.tableize}_#{progressive_present_behaviour}_me").each do |target_that_behaved_on_me|
|
100
|
+
target_that_behaved_on_me.send(Patriarch.undo(behaviour.to_s).underscore,calling_entity,options)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
96
104
|
# Dealing with active behaviour
|
97
105
|
if my_behaviours[behaviour.to_s.underscore.to_sym][:on]
|
98
106
|
acted_on_models = my_behaviours[behaviour.to_s.underscore.to_sym][:on]
|
@@ -103,15 +111,7 @@ class Patriarch::ToolServices::RedisCleanerService < Patriarch::Service
|
|
103
111
|
end
|
104
112
|
end
|
105
113
|
|
106
|
-
|
107
|
-
if my_behaviours[behaviour.to_s.underscore.to_sym][:by]
|
108
|
-
targetted_by_models = my_behaviours[behaviour.to_s.underscore.to_sym][:by]
|
109
|
-
targetted_by_models.each do |targetted_by_model|
|
110
|
-
calling_entity.send("#{targetted_by_model.to_s.tableize}_#{progressive_present_behaviour}_me").each do |target_that_behaved_on_me|
|
111
|
-
target_that_behaved_on_me.send(Patriarch.undo(behaviour.to_s).underscore,calling_entity,options)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
114
|
+
|
115
115
|
end # if my_behaviours.include?
|
116
116
|
|
117
117
|
transac
|
@@ -36,16 +36,16 @@ class Patriarch::ToolServices::RedisExtractorService < Patriarch::Service
|
|
36
36
|
result.map!{ |triplet_id_with_score| [triplet_id_with_score.first[0],tuple.last]}
|
37
37
|
elsif options[:protagonist_type] == :target
|
38
38
|
result.map!{ |triplet_id_with_score| [triplet_id_with_score.first[1],tuple.last]}
|
39
|
-
|
40
|
-
|
39
|
+
elsif options[:protagonist_type] == :medium
|
40
|
+
result.map!{ |triplet_id_with_score| [triplet_id_with_score.first[2],tuple.last]}
|
41
41
|
end
|
42
42
|
else
|
43
43
|
if options[:protagonist_type] == :actor
|
44
44
|
result.map!{ |triplet_id| triplet_id[0] }
|
45
45
|
elsif options[:protagonist_type] == :target
|
46
46
|
result.map!{ |triplet_id| triplet_id[1] }
|
47
|
-
|
48
|
-
|
47
|
+
elsif options[:protagonist_type] == :medium
|
48
|
+
result.map!{ |triplet_id| triplet_id[2] }
|
49
49
|
end
|
50
50
|
end
|
51
51
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Patriarch
|
2
2
|
class Transaction
|
3
3
|
attr_reader :id, :steps, :current_step_number
|
4
|
+
attr_writer :steps
|
4
5
|
attr_reader :type
|
5
6
|
|
6
7
|
forwarded_methods_syms = [:relation_type,:actor_type,:target_type,:medium_type,
|
@@ -47,7 +48,13 @@ module Patriarch
|
|
47
48
|
begin
|
48
49
|
$redis.multi do
|
49
50
|
steps.each do |step|
|
50
|
-
step.
|
51
|
+
if step.is_a? TransactionStep
|
52
|
+
step.execute
|
53
|
+
elsif step.is_a? Transaction
|
54
|
+
step.steps.each do |nested_step|
|
55
|
+
nested_step.execute
|
56
|
+
end
|
57
|
+
end
|
51
58
|
end
|
52
59
|
end
|
53
60
|
rescue Redis::BaseError => e #TODO find redis exception
|
data/lib/patriarch/version.rb
CHANGED
data/patriarch.gemspec
CHANGED
@@ -19,10 +19,10 @@ Gem::Specification.new do |spec|
|
|
19
19
|
|
20
20
|
# Dependencies needed for testing
|
21
21
|
spec.add_development_dependency "rspec"
|
22
|
+
spec.add_development_dependency "guard-rspec"
|
22
23
|
spec.add_development_dependency "activerecord"
|
23
24
|
spec.add_development_dependency "sqlite3"
|
24
|
-
|
25
|
-
|
25
|
+
|
26
26
|
# Other options ...
|
27
27
|
spec.files = `git ls-files`.split($\)
|
28
28
|
spec.executables = spec.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
@@ -1,11 +1,15 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Patriarch::Behaviours do
|
4
|
+
|
5
|
+
|
4
6
|
describe '#add_behaviour' do
|
7
|
+
|
5
8
|
let(:monster) { Monster.create }
|
6
9
|
let(:fallen_angel) { FallenAngel.create }
|
7
10
|
let(:love_letter) { LoveLetter.create }
|
8
11
|
|
12
|
+
|
9
13
|
context 'on a bipartite' do
|
10
14
|
|
11
15
|
before(:all) do
|
@@ -160,6 +164,14 @@ describe Patriarch::Behaviours do
|
|
160
164
|
monster.should respond_to("#{"fallen_angel".pluralize}_i_praise_via_#{"love_letter".pluralize}_ids")
|
161
165
|
end
|
162
166
|
|
167
|
+
it "defines instances methods to retrieve instances of medium model instances used by actor model" do
|
168
|
+
monster.should respond_to("#{"love_letter".pluralize}_i_use_to_praise_#{"fallen_angel".pluralize}")
|
169
|
+
end
|
170
|
+
|
171
|
+
it "defines instances methods to retrieve ids of medium model instances used by actor model" do
|
172
|
+
monster.should respond_to("#{"love_letter".pluralize}_i_use_to_praise_#{"fallen_angel".pluralize}_ids")
|
173
|
+
end
|
174
|
+
|
163
175
|
it "defines instances methods to retrieve model instances having relationships with target model" do
|
164
176
|
progressive_praise = (Verbs::Conjugator.conjugate :praise, :aspect => :progressive).split(/ /).last
|
165
177
|
fallen_angel.should respond_to("#{"monster".pluralize}_#{progressive_praise}_me_via_#{"love_letter".pluralize}")
|
@@ -170,6 +182,19 @@ describe Patriarch::Behaviours do
|
|
170
182
|
fallen_angel.should respond_to("#{"monster".pluralize}_#{progressive_praise}_me_via_#{"love_letter".pluralize}_ids")
|
171
183
|
end
|
172
184
|
|
185
|
+
it "defines instances methods to retrieve instances of medium model instances having relationships with target model" do
|
186
|
+
fallen_angel.should respond_to("#{"love_letter".pluralize}_used_by_#{"monster".pluralize}_to_praise_me")
|
187
|
+
end
|
188
|
+
|
189
|
+
it "defines instances methods to retrieve ids of medium model instances having relationships with target model" do
|
190
|
+
fallen_angel.should respond_to("#{"love_letter".pluralize}_used_by_#{"monster".pluralize}_to_praise_me_ids")
|
191
|
+
end
|
192
|
+
|
193
|
+
# TODO define_alias also ...
|
194
|
+
it "defines instances methods to retrieve ids of model instances entities behaviouring via medium model" do
|
195
|
+
pending('lazyness')
|
196
|
+
end
|
197
|
+
|
173
198
|
it "defines behaviour instance method on actor model" do
|
174
199
|
monster.should respond_to(:praise)
|
175
200
|
end
|
@@ -219,15 +244,32 @@ describe Patriarch::Behaviours do
|
|
219
244
|
|
220
245
|
context 'implements methods that' do
|
221
246
|
it 'lets transaction build without running' do
|
222
|
-
monster.praise(
|
247
|
+
monster.praise(love_letter, fallen_angel, :stop_execution => true).should be_an_instance_of(Patriarch::Transaction)
|
223
248
|
end
|
224
249
|
|
225
250
|
it 'lets undo transaction build without running' do
|
226
|
-
monster.praise(
|
251
|
+
monster.praise(love_letter, fallen_angel, :stop_execution => true).should be_an_instance_of(Patriarch::Transaction)
|
227
252
|
end
|
228
253
|
|
229
254
|
# prepare examples to test both alias and normal methods ...
|
230
255
|
shared_examples 'instances have behaviour working' do
|
256
|
+
|
257
|
+
it "allows actor to remember id of the medium used to behave on target" do
|
258
|
+
monster.love_letters_i_use_to_praise_fallen_angels_ids.should == [love_letter.id]
|
259
|
+
end
|
260
|
+
|
261
|
+
it "allows actor to remember instance of the medium used to behave on target" do
|
262
|
+
monster.love_letters_i_use_to_praise_fallen_angels.should == [love_letter]
|
263
|
+
end
|
264
|
+
|
265
|
+
it "allows target to remember id of the medium used to behave on him" do
|
266
|
+
fallen_angel.love_letters_used_by_monsters_to_praise_me_ids.should == [love_letter.id]
|
267
|
+
end
|
268
|
+
|
269
|
+
it "allows target to remember instance of the medium used to behave on him" do
|
270
|
+
fallen_angel.love_letters_used_by_monsters_to_praise_me.should == [love_letter]
|
271
|
+
end
|
272
|
+
|
231
273
|
it "allows actor to remember target id" do
|
232
274
|
monster.fallen_angels_i_praise_via_love_letters_ids.should == [fallen_angel.id]
|
233
275
|
end
|
@@ -246,19 +288,36 @@ describe Patriarch::Behaviours do
|
|
246
288
|
end
|
247
289
|
|
248
290
|
context 'when doing direct behaviour' do
|
249
|
-
before(:all) { monster.praise fallen_angel
|
291
|
+
before(:all) { monster.praise love_letter,fallen_angel }
|
250
292
|
it_has_behavior 'instances have behaviour working'
|
251
|
-
after(:all) { monster.undo_praise fallen_angel
|
293
|
+
after(:all) { monster.undo_praise love_letter,fallen_angel }
|
252
294
|
end
|
253
295
|
|
254
296
|
context 'when doing behaviour via alias method' do
|
255
|
-
before(:all) { monster.flatter fallen_angel
|
297
|
+
before(:all) { monster.flatter love_letter,fallen_angel }
|
256
298
|
it_has_behavior 'instances have behaviour working'
|
257
|
-
after(:all) { monster.undo_praise fallen_angel
|
299
|
+
after(:all) { monster.undo_praise love_letter,fallen_angel }
|
258
300
|
end
|
259
301
|
|
260
302
|
# prepare examples to test both undo alias and undo normal methods ...
|
261
303
|
shared_examples 'instances have undo behaviour working' do
|
304
|
+
|
305
|
+
it "erase medium id used to behave on target from actor's memory" do
|
306
|
+
monster.love_letters_i_use_to_praise_fallen_angels_ids.should be_empty
|
307
|
+
end
|
308
|
+
|
309
|
+
it "erase medium instance used to behave on target from actor's memory" do
|
310
|
+
monster.love_letters_i_use_to_praise_fallen_angels.should be_empty
|
311
|
+
end
|
312
|
+
|
313
|
+
it "erase medium id used to behave on target from target's memory" do
|
314
|
+
fallen_angel.love_letters_used_by_monsters_to_praise_me_ids.should be_empty
|
315
|
+
end
|
316
|
+
|
317
|
+
it "erase medium instance used to behave on target from target's memory" do
|
318
|
+
fallen_angel.love_letters_used_by_monsters_to_praise_me.should be_empty
|
319
|
+
end
|
320
|
+
|
262
321
|
it "erase target id from actor's memory" do
|
263
322
|
monster.fallen_angels_i_praise_via_love_letters_ids.should be_empty
|
264
323
|
end
|
@@ -278,16 +337,16 @@ describe Patriarch::Behaviours do
|
|
278
337
|
|
279
338
|
context 'when directly undoing behaviour' do
|
280
339
|
before(:all) do
|
281
|
-
monster.praise fallen_angel
|
282
|
-
monster.undo_praise fallen_angel
|
340
|
+
monster.praise love_letter, fallen_angel
|
341
|
+
monster.undo_praise love_letter, fallen_angel
|
283
342
|
end
|
284
343
|
it_has_behavior 'instances have undo behaviour working'
|
285
344
|
end
|
286
345
|
|
287
346
|
context 'when undoing behaviour via undo alias' do
|
288
347
|
before(:all) do
|
289
|
-
monster.praise fallen_angel
|
290
|
-
monster.despise fallen_angel
|
348
|
+
monster.praise love_letter,fallen_angel
|
349
|
+
monster.despise love_letter,fallen_angel
|
291
350
|
end
|
292
351
|
it_has_behavior 'instances have undo behaviour working'
|
293
352
|
end
|
@@ -307,4 +366,32 @@ describe Patriarch::Behaviours do
|
|
307
366
|
FallenAngell.add_behaviour :praise, :medium_between => [:monsterr,:fallenAngell]
|
308
367
|
end
|
309
368
|
end
|
369
|
+
|
370
|
+
context 'when using behaviour on entities that do not allow it' do
|
371
|
+
|
372
|
+
before(:all) do
|
373
|
+
class Monsterr < Monster; end
|
374
|
+
class FallenAngell < FallenAngel; end
|
375
|
+
class LoveLetterr < LoveLetter; end
|
376
|
+
Monsterr.add_behaviour :like, :on => [:fallenAngell], :as => :love, :undo_as => :hate
|
377
|
+
FallenAngell.add_behaviour :like, :by => [:monsterr] , :as => :love
|
378
|
+
|
379
|
+
Monsterr.add_behaviour :praise, :on => [:fallenAngell], :via => [:love_letter]
|
380
|
+
FallenAngell.add_behaviour :praise, :by => [:monsterr], :via => [:love_letter]
|
381
|
+
LoveLetterr.add_behaviour :praise, :medium_between => [:monsterr,:fallenAngell]
|
382
|
+
end
|
383
|
+
|
384
|
+
it "shall fail for bipartite" do
|
385
|
+
expect{ Monsterr.create.like(LoveLetterr.create) }.to raise_error
|
386
|
+
end
|
387
|
+
|
388
|
+
it "shall fail for triparite with unauthorized medium class instances" do
|
389
|
+
expect{ Monsterr.create.praise(Monsterr.create,FallenAngell.create) }.to raise_error
|
390
|
+
end
|
391
|
+
|
392
|
+
it "shall fail for triparite with unauthorized target class instances" do
|
393
|
+
expect{ Monsterr.create.praise(LoveLetterr.create,Monsterr.create) }.to raise_error
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
310
397
|
end # desc Patriarch::Behaviours
|
@@ -43,7 +43,7 @@ describe 'entities including Patriarch::Behaviours #destroy' do
|
|
43
43
|
end
|
44
44
|
|
45
45
|
# This works with ActiveRecord as expected
|
46
|
-
it "
|
46
|
+
it "prevents redis clean" do
|
47
47
|
f = FallenAngel.create
|
48
48
|
m = Monster.create
|
49
49
|
f.lure m
|
@@ -56,27 +56,4 @@ describe 'entities including Patriarch::Behaviours #destroy' do
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
context "when redis transaction fails" do
|
60
|
-
before(:all) do
|
61
|
-
FallenAngel.class_eval do
|
62
|
-
around_destroy :callback_fail
|
63
|
-
def callback_fail
|
64
|
-
# This will trigger Redis::CommandError if executed ...
|
65
|
-
proc = Proc.new { $redis.hset "lal", "lil", 3 }
|
66
|
-
proc_ = Proc.new { $redis.get "lal" }
|
67
|
-
@redis_destroy_transac_object.add_to_queue proc
|
68
|
-
@redis_destroy_transac_object.add_to_queue proc_
|
69
|
-
puts @redis_destroy_transac_object.inspect
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
it "rollbacks sql transaction" do
|
75
|
-
f = FallenAngel.create
|
76
|
-
m = Monster.create
|
77
|
-
f.lure m
|
78
|
-
f.destroy #should fail
|
79
|
-
f.destroyed?.should be_false
|
80
|
-
end
|
81
|
-
end
|
82
59
|
end
|
@@ -9,14 +9,15 @@ describe Patriarch::ToolServices::RedisCleanerService.instance do
|
|
9
9
|
FallenAngel.add_behaviour :like, :by => [:monster]
|
10
10
|
|
11
11
|
# Tripartite behaviour ...
|
12
|
-
FallenAngel.add_behaviour :praise, :
|
13
|
-
Monster.add_behaviour :praise, :
|
12
|
+
FallenAngel.add_behaviour :praise, :by => [:monster], :via => [:loveLetter]
|
13
|
+
Monster.add_behaviour :praise, :on => [:fallenAngel], :via => [:loveLetter]
|
14
14
|
LoveLetter.add_behaviour :praise, :medium_between => [:fallenAngel,:monster]
|
15
15
|
end
|
16
16
|
|
17
17
|
let(:monster) { Monster.create }
|
18
18
|
let(:beast) { Monster.create }
|
19
19
|
let(:love_letter) { LoveLetter.create }
|
20
|
+
let(:fallen_angel) { FallenAngel.create }
|
20
21
|
# Wrong usage when summoning several times fallen_angel within tests; bad knowledge of
|
21
22
|
# let is in cause i think
|
22
23
|
# let(:fallen_angel) { FallenAngel.new }
|
@@ -26,8 +27,8 @@ describe Patriarch::ToolServices::RedisCleanerService.instance do
|
|
26
27
|
it "removes presence into other sets for each behaviour" do
|
27
28
|
f = FallenAngel.create
|
28
29
|
m = Monster.create
|
29
|
-
f.lure m
|
30
30
|
m.like f
|
31
|
+
f.lure m
|
31
32
|
instance.clean_all(f).execute
|
32
33
|
f.monsters_i_lure.should be_empty
|
33
34
|
f.monsters_liking_me.should be_empty
|
@@ -56,17 +57,17 @@ describe Patriarch::ToolServices::RedisCleanerService.instance do
|
|
56
57
|
end
|
57
58
|
|
58
59
|
it "removes given tripartite behaviour binds on other entities" do
|
59
|
-
|
60
|
-
|
61
|
-
instance.clean_behaviour(
|
62
|
-
|
60
|
+
m = Monster.create
|
61
|
+
m.praise love_letter,fallen_angel
|
62
|
+
instance.clean_behaviour(m,:praise).execute
|
63
|
+
fallen_angel.monsters_praising_me_via_love_letters.include?(m).should be_false
|
63
64
|
end
|
64
65
|
|
65
66
|
it "removes given tripartite behaviour binds on self" do
|
66
|
-
|
67
|
-
|
68
|
-
instance.clean_behaviour(
|
69
|
-
|
67
|
+
m = Monster.create
|
68
|
+
m.praise love_letter,fallen_angel
|
69
|
+
instance.clean_behaviour(m,:praise).execute
|
70
|
+
m.fallen_angels_i_praise_via_love_letters.include?(monster).should be_false
|
70
71
|
end
|
71
72
|
|
72
73
|
it "runs within a unique transaction" do
|
data/spec/spec_helper.rb
CHANGED
@@ -53,26 +53,15 @@ class LoveLetter < ActiveRecord::Base; include Patriarch::Behaviours; end
|
|
53
53
|
# Setting standalone database to run tests
|
54
54
|
ActiveRecord::Base.establish_connection(
|
55
55
|
:adapter => "sqlite3",
|
56
|
-
:database => ":memory:"
|
56
|
+
:database => ":memory:" #":memory:"
|
57
57
|
)
|
58
58
|
|
59
59
|
# Load minimal schema for database
|
60
60
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
create_table "love_letters", :force => true do |t|
|
69
|
-
t.datetime "created_at", :null => false
|
70
|
-
t.datetime "updated_at", :null => false
|
61
|
+
capture(:stdout) do
|
62
|
+
ActiveRecord::Schema.define do
|
63
|
+
create_table "fallen_angels", :force => true
|
64
|
+
create_table "love_letters", :force => true
|
65
|
+
create_table "monsters", :force => true
|
71
66
|
end
|
72
|
-
|
73
|
-
create_table "monsters", :force => true do |t|
|
74
|
-
t.datetime "created_at", :null => false
|
75
|
-
t.datetime "updated_at", :null => false
|
76
|
-
end
|
77
|
-
|
78
|
-
end
|
67
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: patriarch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-12-
|
12
|
+
date: 2012-12-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: verbs
|
16
|
-
requirement: &
|
16
|
+
requirement: &17816280 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *17816280
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: railties
|
27
|
-
requirement: &
|
27
|
+
requirement: &17815860 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *17815860
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: activerecord
|
38
|
-
requirement: &
|
38
|
+
requirement: &17815420 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *17815420
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rspec
|
49
|
-
requirement: &
|
49
|
+
requirement: &17814980 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,21 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *17814980
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: guard-rspec
|
60
|
+
requirement: &17814500 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *17814500
|
58
69
|
- !ruby/object:Gem::Dependency
|
59
70
|
name: activerecord
|
60
|
-
requirement: &
|
71
|
+
requirement: &17813840 !ruby/object:Gem::Requirement
|
61
72
|
none: false
|
62
73
|
requirements:
|
63
74
|
- - ! '>='
|
@@ -65,10 +76,10 @@ dependencies:
|
|
65
76
|
version: '0'
|
66
77
|
type: :development
|
67
78
|
prerelease: false
|
68
|
-
version_requirements: *
|
79
|
+
version_requirements: *17813840
|
69
80
|
- !ruby/object:Gem::Dependency
|
70
81
|
name: sqlite3
|
71
|
-
requirement: &
|
82
|
+
requirement: &17813220 !ruby/object:Gem::Requirement
|
72
83
|
none: false
|
73
84
|
requirements:
|
74
85
|
- - ! '>='
|
@@ -76,7 +87,7 @@ dependencies:
|
|
76
87
|
version: '0'
|
77
88
|
type: :development
|
78
89
|
prerelease: false
|
79
|
-
version_requirements: *
|
90
|
+
version_requirements: *17813220
|
80
91
|
description: Patriach is about adding behaviours on the fly to good old active record
|
81
92
|
models.
|
82
93
|
email:
|