ventable 0.0.2 → 0.0.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/README.md +35 -10
- data/lib/ventable/event.rb +14 -3
- data/lib/ventable/version.rb +1 -1
- data/spec/ventable/ventable_spec.rb +22 -1
- metadata +2 -2
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
|
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
|
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
|
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
|
data/lib/ventable/event.rb
CHANGED
@@ -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
|
-
|
81
|
-
|
82
|
-
|
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
|
data/lib/ventable/version.rb
CHANGED
@@ -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 == :
|
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.
|
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-
|
12
|
+
date: 2013-02-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|