patriarch 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|