README.md in ventable-1.0.0 vs README.md in ventable-1.2.0
- old
+ new
@@ -1,16 +1,49 @@
-[![Gem Version](https://badge.fury.io/rb/ventable.png)](http://badge.fury.io/rb/ventable)
-[![Build status](https://secure.travis-ci.org/kigster/ventable.png)](http://travis-ci.org/kigster/ventable)
-[![Code Climate](https://codeclimate.com/github/kigster/ventable.png)](https://codeclimate.com/github/kigster/ventable)
+[![Gem Version](https://badge.fury.io/rb/ventable.svg)](https://badge.fury.io/rb/ventable)
+[![Build Status](https://travis-ci.org/kigster/ventable.svg?branch=master)](https://travis-ci.org/kigster/ventable)
+[![Code Climate](https://codeclimate.com/github/kigster/ventable/badges/gpa.svg)](https://codeclimate.com/github/kigster/ventable)
+[![Downloads](http://ruby-gem-downloads-badge.herokuapp.com/ventable?type=total)](https://rubygems.org/gems/ventable)
+[![Gitter](https://img.shields.io/gitter/room/gitterHQ/gitter.svg)](https://gitter.im/kigster/ventable)
+[![Test Coverage](https://api.codeclimate.com/v1/badges/c28d141c978293886d21/test_coverage)](https://codeclimate.com/github/kigster/ventable/test_coverage)
+
+
# Ventable
-Simple eventing gem that implements Observable pattern, but with more options, ability to group observers and wrap
-them in arbitrary blocks of code. For example, when a certain event fires, some observers may be called within
-a transaction context, while others maybe called outside of the transaction context.
+This gem is a variation of the [Observer Design Pattern](https://en.wikipedia.org/wiki/Observer_pattern).
+In particular:
+
+ * Ventable requires creation of simple event classes that may carry data and be serialized.
+ * Observers can be grouped together, and notified within a pre-defined `Proc`. For example, using grouping some observers may be called within the boundaries of a database transaction, while others maybe called outside of it.
+ * Ventable allows both compile time and run time observer binding.
+ * Ventable calls specific method on each observer, using automatically derived method name from the event class. A generic `#handle_event` method is also supported.
+
+Limitations:
+
+ * At the moment, Ventable can only notify observers within the current ruby process.
+
+## Plugins
+
+Ventable has several plugins that add various functionality on top of the basic event dispatch mechanism.
+
+ * [ventable-statsd](https://github.com/kigster/ventable-statsd) is an extension that allows notifying Statsd whenever an event occurs.
+ * [simple-feed](https://github.com/kigster/simple-feed) is a generic implementation of the activity feed concept commonly seen on social networks, and it integrates nicely with Ventable.
+
+## Ruby Versions
+
+This gem has been verified to work in the following ruby versions:
+
+ * MRI Ruby
+ * 1.9.3-p551
+ * 2.2
+ * 2.3
+ * 2.4
+
+The gem also likely works with non-MRI rubies, but it has not been tested.
+
## Installation
Add this line to your application's Gemfile:
gem 'ventable'
@@ -23,18 +56,21 @@
$ gem install ventable
## Usage
-1. Create your own plain ruby Event class that optionally carries some data important to the event. Include module ```Ventable::Event```.
+1. Create your own plain ruby Event class that optionally carries some data important to the event. Include module `Ventable::Event`.
+
2. Create one or more observers. Observer can be any class that implements event handler method as a class method, such as a
- generic method ```self.handle(event)``` or a more specific method mapped to the event name: say for event UserRegistered the
- callback event would be ```self.handle_user_registered(event)```
-3. Register your observers with the event using ```notifies``` event method, or register groups using ```group``` method, and then
- use ```notify``` with options ```inside: :group_name```
-4. Instantiate your event class (optionally with some data), and call ```fire!``` method.
+ generic method `self.handle(event)` or a more specific method mapped to the event name: say for event UserRegistered the
+ callback event would be `self.handle_user_registered(event)`
+3. Register your observers with the event using `notifies` event method, or register groups using `group` method, and then
+ use `notify` with options `inside: :group_name`
+
+4. Instantiate your event class (optionally with some data), and call `publish` or, a deprecated `fire!` method.
+
## Example
```ruby
require 'ventable'
@@ -60,11 +96,11 @@
# Register the observer
AlarmSoundEvent.notifies SleepingPerson
# Create and fire the event
-AlarmSoundEvent.new(Date.new).fire!
+AlarmSoundEvent.new(Date.new).publish
```
## Using #configure and groups
Events can be configured to call observers in groups, with an optional block around it. Using groups
@@ -99,11 +135,11 @@
# these two observers are called at the end of the transaction group,
# but before AnotherObserverClass is notified.
notifies ObserverClass1, ObserverClass2, inside: :transaction
end
-SomeEvent.new.fire!
+SomeEvent.new.publish
```
## Callback Method Name
When the observer is notified, Ventable library will call a class method on your observer, with the name determined
@@ -117,27 +153,27 @@
## Guidelines for Using Ventable with Rails
You should start by defining your event library for your application (list of events
that are important to you), you can place these files anywhere you like, such as
-```lib/events``` or ```app/events```, etc.
+`lib/events` or `app/events`, etc.
-It is recommended to ```configure``` all events and their observers in the ```event_initializer.rb``` file,
-inside the ```config/ininitalizers``` folder. You may need to require your events in that file also.
+It is recommended to `configure` all events and their observers in the `event_initializer.rb` file,
+inside the `config/ininitalizers` folder. You may need to require your events in that file also.
When your event is tied to a creation of a "first class objects", such as user registration,
it is recommended to create the User record first, commit it to the database, and then throw
-a ```UserRegisteredEvent.new(user).fire!```, and have all subsequent logic broeken into
-their respective classes. For example, if you need to send an email to the user, have a ```Mailer```
-class observe the ```UserRegisteredEvent```, and so all the mailing logic can live inside the ```Mailer```
-class, instead of, say, registration controller directly calling ```Mailer.deliver_user_registration!(user)```.
+a `UserRegisteredEvent.new(user).publish`, and have all subsequent logic broeken into
+their respective classes. For example, if you need to send an email to the user, have a `Mailer`
+class observe the `UserRegisteredEvent`, and so all the mailing logic can live inside the `Mailer`
+class, instead of, say, registration controller directly calling `Mailer.deliver_user_registration!(user)`.
The callback method will receive the event, that wraps the User instance, or any other useful data necessary.
## Integration with tests
There are times when it may be desirable to disable all eventing. For instance, when writing unit tests,
-testing that events are fired may be useful, but integrating with all observers adds complexity and confusion.
+testing that events are published may be useful, but integrating with all observers adds complexity and confusion.
In these cases, Ventable may be globally disabled.
```ruby
## in spec_helper
@@ -151,17 +187,17 @@
Now in a spec file:
```ruby
describe "Stuff", eventing: false do
it 'does stuff' do
- ... my code that fires events, in isolation from event observers
+ ... my code that publishes events, in isolation from event observers
end
- it 'tests that events are fired, using stubs' do
- event = double(fire!: true)
+ it 'tests that events are published, using stubs' do
+ event = double(publish: true)
allow(MyEvent).to receive(:new).and_return(event)
... my code that should fire event
- expect(event).to have_received(:fire!)
+ expect(event).to have_received(:publish)
end
end
describe 'Other stuff' do
it 'actually calls through to all observers, so valid data is required' do