ventable 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -22,13 +22,13 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
- 1. Create your own plain ruby class that optionally carries some data important to the event. Include module Ventable::Event.
25
+ 1. Create your own plain ruby Event class that optionally carries some data important to the event. Include module ```Ventable::Event```.
26
26
  2. Create one or more observers. Observer can be any class that implements event handler method as a class method, such as a
27
27
  generic method ```self.handle_event(event)``` or a more specific method mapped to the event name: say for event UserRegistered the
28
28
  callback event would be ```self.handle_user_registered_event(event)```
29
29
  3. Register your observers with the event using ```notifies``` event method, or register groups using ```group``` method, and then
30
30
  use ```notify``` with options ```inside: :group_name```
31
- 4. Instantiate your event (optionally with data), and call fire!() method.
31
+ 4. Instantiate your event class (optionally with some data), and call ```fire!``` method.
32
32
 
33
33
  ## Example
34
34
 
@@ -53,7 +53,6 @@ class SleepingPerson
53
53
  puts "snoozing at #{event.wakeup_time}"
54
54
  self.snooze(5)
55
55
  end
56
- #.. implementation
57
56
  end
58
57
 
59
58
  # Register the observer
@@ -65,7 +64,6 @@ AlarmSoundEvent.new(Date.new).fire!
65
64
 
66
65
  ## Using #configure and groups
67
66
 
68
-
69
67
  Events can be configured to call observers in groups, with an optional block around it.
70
68
 
71
69
  ```ruby
@@ -84,25 +82,52 @@ SomeEvent.configure do
84
82
  # first observer to be called
85
83
  notifies FirstObserverClassToBeCalled
86
84
 
87
- # this group will be notified next
85
+ # any observers in this group will be notified next...
88
86
  group :transaction, &transaction
89
87
 
90
- # this block is executed after the group
88
+ # this block will be run as the first member of the group
91
89
  notifies inside: :transaction do
92
90
  # perform block
93
91
  end
94
92
 
95
- # these observers are run inside the transaction block
96
- notifies ObserverClass1, ObserverClass2, inside: :transaction
97
93
 
98
- # this one is the last to be notified
94
+ # this observer gets notified after all observers inside :transactions are notified
99
95
  notifies AnotherObserverClass
96
+
97
+ # these two observers are called at the end of the transaction group,
98
+ # but before AnotherObserverClass is notified.
99
+ notifies ObserverClass1, ObserverClass2, inside: :transaction
100
100
  end
101
101
 
102
102
  SomeEvent.new.fire!
103
-
104
103
  ```
105
104
 
105
+ ## Guidelines for Using Ventable with Rails
106
+
107
+ You should start by defining your event library for your application (list of events
108
+ that are important to you), you can place these files anywhere you like, such as
109
+ ```lib/events``` or ```app/events```, etc.
110
+
111
+ It is recommended to configure all events and observers in the ```event_initializer.rb``` file,
112
+ inside the ```config/ininitalizers``` folder.
113
+
114
+ When your event is tied to a creation of a "first class objects", such as user registration,
115
+ it is recommended to create the User record first, commit it to the database, and then throw
116
+ a ```ruby UserRegisteredEvent.new(user).fire!```, and have all subsequent logic broeken into
117
+ their respective classes. For example, if you need to send email to the user, have a ```Mailer```
118
+ class observe the ```UserRegisteredEvent```, and so all the mailing logic can live in the ```Mailer```
119
+ class, instead of, say, registration controller. The callback method will receive the event, that
120
+ wraps the User instance, or any other useful data necessary.
121
+
122
+ ## Further Discussion
123
+
124
+ It is worth mentioning that in the current form this gem is simply a software design pattern. It helps
125
+ decouple code that performs tasks related to the same event (such as user registration, or comment posting),
126
+ but unrelated to each other (such as sending email to the user).
127
+
128
+ Future versions of this gem may offer a way to further decouple observers, by allowing them to be notified
129
+ via a background queue, such as Sidekiq or Resque. If you are interested in helping, please email the author.
130
+
106
131
  ## Contributing
107
132
 
108
133
  1. Fork it
@@ -1,6 +1,9 @@
1
1
  require 'set'
2
2
 
3
3
  module ::Ventable
4
+ class Error < RuntimeError
5
+ end
6
+
4
7
  module Event
5
8
  def self.included(klazz)
6
9
  klazz.instance_eval do
@@ -57,6 +60,9 @@ module ::Ventable
57
60
  observer_set = self.observers
58
61
  if options[:inside]
59
62
  observer_entry = self.find_observer_group(options[:inside])
63
+ if observer_entry.nil?
64
+ raise Ventable::Error.new("No group with name #{options[:inside]} found.")
65
+ end
60
66
  observer_set = observer_entry[:observers]
61
67
  end
62
68
  observer_list.each { |o| observer_set << o } unless observer_list.empty?
@@ -76,10 +82,15 @@ module ::Ventable
76
82
  self.observers.find { |o| o.is_a?(Hash) && o[:name] == name }
77
83
  end
78
84
 
85
+ # Determine method name to call when notifying observers from this event.
79
86
  def default_callback_method
80
- target = self
81
- method = "handle_" + target.name.gsub(/.*::/,'').underscore.gsub(/_event/, '') + "_event"
82
- method.to_sym
87
+ if respond_to?(:ventable_callback_method_name)
88
+ self.ventable_callback_method_name
89
+ else
90
+ target = self
91
+ method = "handle_" + target.name.gsub(/::/,'__').underscore.gsub(/_event/, '') + "_event"
92
+ method.to_sym
93
+ end
83
94
  end
84
95
  end
85
96
  end
@@ -1,3 +1,3 @@
1
1
  module Ventable
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -128,12 +128,20 @@ describe Ventable do
128
128
  class SomeOtherStuffHappened
129
129
  include Ventable::Event
130
130
  end
131
+ class ClassWithCustomCallbackMethodEvent
132
+ include Ventable::Event
133
+
134
+ def self.ventable_callback_method_name
135
+ :handle_my_special_event
136
+ end
137
+ end
131
138
  end
132
139
 
133
140
  it "should properly set the callback method name" do
134
141
  SomeAwesomeEvent.default_callback_method.should == :handle_some_awesome_event
135
- Blah::AnotherSweetEvent.default_callback_method.should == :handle_another_sweet_event
142
+ Blah::AnotherSweetEvent.default_callback_method.should == :handle_blah__another_sweet_event
136
143
  SomeOtherStuffHappened.default_callback_method.should == :handle_some_other_stuff_happened_event
144
+ ClassWithCustomCallbackMethodEvent.default_callback_method.should == :handle_my_special_event
137
145
  end
138
146
  end
139
147
 
@@ -165,5 +173,18 @@ describe Ventable do
165
173
  notified_observer.should be_true
166
174
  called_transaction.should be_true
167
175
  end
176
+
177
+ it "throws exception if :inside references unknown group" do
178
+ begin
179
+ TestEvent.configure do
180
+ notifies inside: :transaction do
181
+ # some stuff
182
+ end
183
+ end
184
+ fail "Shouldn't reach here, must throw a valid exception"
185
+ rescue Exception => e
186
+ e.class.should == Ventable::Error
187
+ end
188
+ end
168
189
  end
169
190
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ventable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-21 00:00:00.000000000 Z
12
+ date: 2013-02-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec