patriarch 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml ADDED
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 1.9.2
5
+
6
+ notifications:
7
+ irc:
8
+ - "irc.iiens.net#blackbird_prive"
9
+
10
+ branches:
11
+ only:
12
+ - master
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Build Status](https://travis-ci.org/giglemad/patriarch.png)](https://travis-ci.org/giglemad/patriarch)
2
+ [![Dependency Status](https://gemnasium.com/giglemad/patriarch.png)](https://gemnasium.com/giglemad/patriarch)
1
3
  # Patriarch
2
4
 
3
5
  N-N tables are often a pain to deal with in SQL especially when you want to
@@ -32,11 +34,6 @@ Add this line to your application's Gemfile:
32
34
  gem 'patriarch'
33
35
  ```
34
36
 
35
- Or this one if you want to be up-to-date in real time
36
- ```ruby
37
- gem 'patriarch', :git => 'https://github.com/nateware/redis-objects.git'
38
- ```
39
-
40
37
  And then execute:
41
38
 
42
39
  $ bundle update
@@ -44,6 +41,10 @@ And then execute:
44
41
  Or install it yourself as:
45
42
 
46
43
  $ gem install patriarch
44
+
45
+ Patriarch needs to generate some file before you use it, type this:
46
+
47
+ $ rails generate patriarch:install
47
48
 
48
49
  ## Usage
49
50
 
@@ -236,5 +237,7 @@ user.posts_i_comment_via_messages_ids :with_medium => true
236
237
 
237
238
  ## Thanks
238
239
 
240
+ I'd like to give credit to @nateware who built the awesome Redis-Objects this gem rely on to perform operations against redis.
241
+
239
242
  Thanks for using this gem ! If you are really really grateful or want to talk about this and happen to be in Paris, you
240
243
  can issue a beer pull request that i will happily merge.
data/Rakefile CHANGED
@@ -1,2 +1,7 @@
1
1
  #!/usr/bin/env rake
2
2
  require "bundler/gem_tasks"
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ task :default => :spec
7
+
@@ -1,5 +1,5 @@
1
1
  require "redis/objects/sorted_sets"
2
-
2
+ require 'ostruct'
3
3
  # Patriarch::Transaction instances are composed of transaction steps that each represent
4
4
  # a behaviour being triggered. RelationshipBuilderServices allow Services managing transaction
5
5
  # flow to build transaction step correctly. This deals with transaction step needed to represent
@@ -16,8 +16,11 @@ class Patriarch::DAOServices::BipartiteRelationshipBuilderService < Patriarch::S
16
16
  actor_dao = dao_tab[:actor]
17
17
  target_dao = dao_tab[:target]
18
18
 
19
- l = build_lambda_for_create(actor_dao,transaction_item.target_id,t)
20
- ll = build_lambda_for_create(target_dao,transaction_item.actor_id,t)
19
+ l = build_ostruct_for_create(actor_dao,transaction_item.target_id,t)
20
+ ll = build_ostruct_for_create(target_dao,transaction_item.actor_id,t)
21
+
22
+ p "#{l.inspect} is creating on key #{actor_dao.key} : #{transaction_item.target_type} #{transaction_item.target_id}"
23
+ p "#{ll.inspect} is creating on key #{target_dao.key} : #{transaction_item.actor_type} #{transaction_item.actor_id}"
21
24
 
22
25
  # care about that, should be encapsulated into a beautiful add_to_queue method
23
26
  transaction_item.add_to_queue l
@@ -32,12 +35,11 @@ class Patriarch::DAOServices::BipartiteRelationshipBuilderService < Patriarch::S
32
35
 
33
36
  actor_dao = dao_tab[:actor]
34
37
  target_dao = dao_tab[:target]
35
-
36
- l = lambda { actor_dao.delete transaction_item.target_id }
37
- ll = lambda { target_dao.delete transaction_item.actor_id }
38
38
 
39
- # p "#{l.inspect} is deleting on key #{actor_dao.key} : #{transaction_item.target_type} #{transaction_item.target_id}"
40
- # p "#{ll.inspect} is deleting on key #{target_dao.key} : #{transaction_item.actor_type} #{transaction_item.actor_id}"
39
+ #l = proc { actor_dao.delete transaction_item.target_id }
40
+ #ll = proc { target_dao.delete transaction_item.actor_id }
41
+ l = OpenStruct.new(:method_sym => :delete ,:dao => actor_dao, :args => [transaction_item.target_id])
42
+ ll = OpenStruct.new(:method_sym => :delete ,:dao => target_dao, :args => [transaction_item.actor_id])
41
43
 
42
44
  transaction_item.add_to_queue l
43
45
  transaction_item.add_to_queue ll
@@ -47,12 +49,14 @@ class Patriarch::DAOServices::BipartiteRelationshipBuilderService < Patriarch::S
47
49
  # @param [Redis::Objects] dao
48
50
  # @param [Array] ids
49
51
  # @param [Time] time
50
- # Returns lambda objects that store a redis operation
51
- def build_lambda_for_create(dao,id,time)
52
+ # Returns ostruct objects that store parameters to execute a redis operation
53
+ def build_ostruct_for_create(dao,id,time)
52
54
  if dao.is_a? Redis::SortedSet
53
- return lambda { dao.add id, time }
55
+ return OpenStruct.new(:method_sym => :add ,:dao => dao, :args => [id,time])
56
+ # return lambda { dao.add ids, time }
54
57
  else
55
- return lambda { dao.add id }
58
+ return OpenStruct.new(:method_sym => :add ,:dao => dao, :args => [id])
59
+ # return lambda { dao.add ids }
56
60
  end
57
- end
61
+ end
58
62
  end
@@ -20,9 +20,9 @@ class Patriarch::DAOServices::TripartiteRelationshipBuilderService < Patriarch::
20
20
 
21
21
  protagonist_ids = [transaction_item.actor_id,transaction_item.target_id,transaction_item.medium_id]
22
22
 
23
- l = build_lambda_for_create(actor_dao,protagonist_ids,t)
24
- ll = build_lambda_for_create(target_dao,protagonist_ids,t)
25
- lll = build_lambda_for_create(medium_dao,protagonist_ids,t)
23
+ l = build_ostruct_for_create(actor_dao,protagonist_ids,t)
24
+ ll = build_ostruct_for_create(target_dao,protagonist_ids,t)
25
+ lll = build_ostruct_for_create(medium_dao,protagonist_ids,t)
26
26
 
27
27
  # care about that, should be encapsulated into a beautiful add_to_queue method
28
28
  transaction_item.add_to_queue l
@@ -42,10 +42,14 @@ class Patriarch::DAOServices::TripartiteRelationshipBuilderService < Patriarch::
42
42
 
43
43
  protagonist_ids = [transaction_item.actor_id,transaction_item.target_id,transaction_item.medium_id]
44
44
 
45
- l = lambda { actor_dao.delete protagonist_ids }
46
- ll = lambda { target_dao.delete protagonist_ids }
47
- lll = lambda { medium_dao.delete protagonist_ids }
45
+ #l = lambda { actor_dao.delete protagonist_ids }
46
+ #ll = lambda { target_dao.delete protagonist_ids }
47
+ #lll = lambda { medium_dao.delete protagonist_ids }
48
48
 
49
+ l = OpenStruct.new(:method_sym => :delete ,:dao => actor_dao, :args => [protagonist_ids])
50
+ ll = OpenStruct.new(:method_sym => :delete ,:dao => target_dao, :args => [protagonist_ids])
51
+ lll = OpenStruct.new(:method_sym => :delete ,:dao => medium_dao, :args => [protagonist_ids])
52
+
49
53
  transaction_item.add_to_queue l
50
54
  transaction_item.add_to_queue ll
51
55
  transaction_item.add_to_queue lll
@@ -55,12 +59,14 @@ class Patriarch::DAOServices::TripartiteRelationshipBuilderService < Patriarch::
55
59
  # @param [Redis::Objects] dao
56
60
  # @param [Array] ids
57
61
  # @param [Time] time
58
- # Returns lambda objects that store a redis operation
59
- def build_lambda_for_create(dao,ids,time)
62
+ # Returns ostruct objects that store parameters to execute a redis operation
63
+ def build_ostruct_for_create(dao,ids,time)
60
64
  if dao.is_a? Redis::SortedSet
61
- return lambda { dao.add ids, time }
65
+ return OpenStruct.new(:method_sym => :add ,:dao => dao, :args => [ids,time])
66
+ # return lambda { dao.add ids, time }
62
67
  else
63
- return lambda { dao.add ids }
68
+ return OpenStruct.new(:method_sym => :add ,:dao => dao, :args => [ids])
69
+ # return lambda { dao.add ids }
64
70
  end
65
71
  end
66
72
  end
@@ -123,8 +123,6 @@ class Patriarch::ToolServices::RedisCleanerService < Patriarch::Service
123
123
  end
124
124
  end
125
125
  end
126
-
127
-
128
126
  end # if my_behaviours.include?
129
127
 
130
128
  transac
@@ -83,8 +83,8 @@ module Patriarch
83
83
  transaction_queue
84
84
  end
85
85
 
86
- def add_to_queue(proc)
87
- current_step.add_to_queue(proc)
86
+ def add_to_queue(instructions)
87
+ current_step.add_to_queue(instructions)
88
88
  end
89
89
 
90
90
  alias :queue :transaction_queue
@@ -43,18 +43,22 @@ module Patriarch
43
43
  target_type.to_s.camelize.constantize.find target_id
44
44
  end
45
45
 
46
- # execute the redis instruction embedded into this step
46
+ # execute the redis instructions embedded into this step against
47
+ # instructions are a dao, a method to call upon and its argument embedded into a OpenStruct
48
+ # before Patriarch 0.2.5, was embedded directly in a proc, was a complete failure for unknown reasons
47
49
  # Patriach::Transaction use this method on each of the steps it registered within a multi block
48
50
  def execute
49
- queue.each do |redis_instruction|
50
- redis_instruction.call
51
+ queue.each do |redis_ostruct_instruction|
52
+ os = redis_ostruct_instruction
53
+ dao, method_sym, args = [os.dao,os.method_sym,os.args]
54
+ dao.send(method_sym,*args)
55
+ # deprecated, remove this : redis_instruction.call
51
56
  end
52
57
  end
53
58
 
54
- # Add a redis instruction embedded in a proc into the queue of instruction to be processed of this step
55
- # @param [Proc] proc the chunk of executable redis code embedded into a Proc to be added to queue
56
- def add_to_queue(proc)
57
- queue << proc
59
+ # @param [OpenStruct] ostruct dao with parameters and method to call embedded here to be processed later
60
+ def add_to_queue(ostruct)
61
+ queue << ostruct
58
62
  end
59
63
  end
60
64
  end
@@ -1,3 +1,3 @@
1
1
  module Patriarch
2
- VERSION = "0.2.4"
2
+ VERSION = "0.2.5"
3
3
  end
data/patriarch.gemspec CHANGED
@@ -2,8 +2,8 @@
2
2
  require File.expand_path('../lib/patriarch/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |spec|
5
- spec.authors = ["Hugo Lepetit"]
6
- spec.email = ["hugo@blackbid.co"]
5
+ spec.authors = ["Hugo Lepetit","Loïc Delmaire"]
6
+ spec.email = ["hugo@blackbid.co","loic@blackbird.co"]
7
7
  spec.description = %q{Patriach is about adding behaviours on the fly to good old active record models.}
8
8
  spec.summary = %q{Manage relationships between instances of your models easily}
9
9
  spec.homepage = "https://github.com/giglemad/patriarch"
@@ -22,20 +22,28 @@ describe Patriarch::DAOServices::BipartiteRelationshipBuilderService do
22
22
  it "shall insert processable lambdas into queues when create is called" do
23
23
  expect{
24
24
  instance.create(@transac)
25
- }.to change{ @transac.transaction_queue.select{ |queue_element| queue_element.is_a? Proc}.size }.by(2)
25
+ }.to change{ @transac.transaction_queue.select{ |queue_element| queue_element.is_a? OpenStruct}.size }.by(2)
26
26
 
27
27
  expect{
28
- @transac.transaction_queue.each{ |proc| proc.call }
28
+ @transac.transaction_queue.each do |redis_ostruct_instruction|
29
+ os = redis_ostruct_instruction
30
+ dao, method_sym, args = [os.dao,os.method_sym,os.args]
31
+ dao.send(method_sym,*args)
32
+ end
29
33
  }.to change{ $redis.keys.size}.by(2)
30
34
  end
31
35
 
32
36
  it "shall insert processable lambdas into queues when destroy is called" do
33
37
  expect{
34
38
  instance.destroy(@transac)
35
- }.to change{ @transac.transaction_queue.select{ |queue_element| queue_element.is_a? Proc}.size }.by(2)
39
+ }.to change{ @transac.transaction_queue.select{ |queue_element| queue_element.is_a? OpenStruct}.size }.by(2)
36
40
 
37
41
  expect{
38
- @transac.transaction_queue.each{ |proc| proc.call }
42
+ @transac.transaction_queue.each do |redis_ostruct_instruction|
43
+ os = redis_ostruct_instruction
44
+ dao, method_sym, args = [os.dao,os.method_sym,os.args]
45
+ dao.send(method_sym,*args)
46
+ end
39
47
  }.to change{ $redis.info["total_commands_processed"].to_i}.by(3)
40
48
  end
41
49
 
@@ -43,4 +51,4 @@ describe Patriarch::DAOServices::BipartiteRelationshipBuilderService do
43
51
  $redis.del "monster:#{monster.id}:patriarch_fallen_angels_i_like"
44
52
  $redis.del "fallen_angel:#{fallen_angel.id}:patriarch_monsters_liking_me"
45
53
  end
46
- end
54
+ end
@@ -24,20 +24,28 @@ describe Patriarch::DAOServices::TripartiteRelationshipBuilderService do
24
24
  it "shall insert processable lambdas into queues when create is called" do
25
25
  expect{
26
26
  instance.create(@transac)
27
- }.to change{ @transac.transaction_queue.select{ |queue_element| queue_element.is_a? Proc}.size }.by(3)
27
+ }.to change{ @transac.transaction_queue.select{ |queue_element| queue_element.is_a? OpenStruct}.size }.by(3)
28
28
 
29
29
  expect{
30
- @transac.transaction_queue.each{ |proc| proc.call }
30
+ @transac.transaction_queue.each do |redis_ostruct_instruction|
31
+ os = redis_ostruct_instruction
32
+ dao, method_sym, args = [os.dao,os.method_sym,os.args]
33
+ dao.send(method_sym,*args)
34
+ end
31
35
  }.to change{ $redis.keys.size}.by(3)
32
36
  end
33
37
 
34
38
  it "shall insert processable lambdas into queues when destroy is called" do
35
39
  expect{
36
40
  instance.destroy(@transac)
37
- }.to change{ @transac.transaction_queue.select{ |queue_element| queue_element.is_a? Proc}.size }.by(3)
41
+ }.to change{ @transac.transaction_queue.select{ |queue_element| queue_element.is_a? OpenStruct}.size }.by(3)
38
42
 
39
43
  expect{
40
- @transac.transaction_queue.each{ |proc| proc.call }
44
+ @transac.transaction_queue.each do |redis_ostruct_instruction|
45
+ os = redis_ostruct_instruction
46
+ dao, method_sym, args = [os.dao,os.method_sym,os.args]
47
+ dao.send(method_sym,*args)
48
+ end
41
49
  }.to change{ $redis.info["total_commands_processed"].to_i}.by(4)
42
50
  end
43
51
 
@@ -46,4 +54,4 @@ describe Patriarch::DAOServices::TripartiteRelationshipBuilderService do
46
54
  $redis.del "fallen_angel:#{fallen_angel.id}:patriarch_monsters_prasing_me_via_love_letters"
47
55
  $redis.del "love_letter:#{fallen_angel.id}:patriarch_monsters_prasing_fallen_angels_via_me"
48
56
  end
49
- end
57
+ end
@@ -5,6 +5,8 @@ describe 'entities including Patriarch::Behaviours #destroy' do
5
5
  before(:all) do
6
6
  Monster.add_behaviour :lure, :by => [:fallenAngel]
7
7
  FallenAngel.add_behaviour :lure, :on => [:monster]
8
+ FallenAngel.add_behaviour :lure, :by => [:fallenAngel]
9
+ FallenAngel.add_behaviour :lure, :on => [:fallenAngel]
8
10
  Monster.add_behaviour :like, :on => [:fallenAngel]
9
11
  FallenAngel.add_behaviour :like, :by => [:monster]
10
12
 
@@ -24,12 +26,65 @@ describe 'entities including Patriarch::Behaviours #destroy' do
24
26
  f.lure m
25
27
  m.like f
26
28
  f.destroy
29
+ f.destroyed?.should be_true
27
30
  f.monsters_i_lure.should be_empty
28
31
  f.monsters_liking_me.should be_empty
29
32
  m.fallen_angels_i_like.include?(f).should be_false
30
33
  m.fallen_angels_luring_me.include?(f).should be_false
31
34
  end
32
35
 
36
+ context "cascading style" do
37
+ # KIKOOOOOOOO Test for Skelz0r
38
+ before(:all) do
39
+ FallenAngel.class_eval do
40
+ before_destroy :destroy_fallen_angels_i_lure
41
+ def destroy_fallen_angels_i_lure
42
+ self.fallen_angels_i_lure.each do |lured_fallen_angel|
43
+ lured_fallen_angel.destroy
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ it "cleans safely on top of the 'transitive' behaviour chain" do
50
+ f,fa,fal = [FallenAngel.create,FallenAngel.create,FallenAngel.create]
51
+ f.lure fa; fa.lure fal
52
+
53
+ f.destroy
54
+
55
+ f.fallen_angels_i_lure.should be_empty
56
+ fa.fallen_angels_i_lure.should be_empty
57
+
58
+ fa.destroyed?.should be_false
59
+ FallenAngel.where(:id => fa.id).should be_empty
60
+
61
+ fal.destroyed?.should be_false
62
+ FallenAngel.where(:id => fal.id).should be_empty
63
+
64
+ f.destroyed?.should be_true
65
+ FallenAngel.where(:id => f.id).should be_empty
66
+ end
67
+
68
+ it "cleans safely anywhere in the 'transitive' behaviour chain" do
69
+ f,fa,fal = [FallenAngel.create,FallenAngel.create,FallenAngel.create]
70
+ f.lure fa; fa.lure fal
71
+
72
+ fa.destroy
73
+
74
+ f.fallen_angels_i_lure.should be_empty
75
+ fa.fallen_angels_i_lure.should be_empty
76
+
77
+ fa.destroyed?.should be_true
78
+ FallenAngel.where(:id => fa.id).should be_empty
79
+
80
+ fal.destroyed?.should be_false
81
+ FallenAngel.where(:id => fa.id).should be_empty
82
+
83
+ f.destroyed?.should be_false
84
+ Array(FallenAngel.where(:id => f.id)).should == [f]
85
+ end
86
+ end
87
+
33
88
  context ' when another callback fails' do
34
89
 
35
90
  # they do not trigger a rollback when they return false
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: patriarch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Hugo Lepetit
9
+ - Loïc Delmaire
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2012-12-31 00:00:00.000000000 Z
13
+ date: 2013-02-09 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: verbs
@@ -127,11 +128,13 @@ description: Patriach is about adding behaviours on the fly to good old active r
127
128
  models.
128
129
  email:
129
130
  - hugo@blackbid.co
131
+ - loic@blackbird.co
130
132
  executables: []
131
133
  extensions: []
132
134
  extra_rdoc_files: []
133
135
  files:
134
136
  - .gitignore
137
+ - .travis.yml
135
138
  - Gemfile
136
139
  - LICENSE
137
140
  - README.md