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 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