active_spy¶ ↑
Watch for a method call in any class and run before/after callbacks. You can even watch your Rails models for events (like create, update, destroy), send these events to a event-runner instance and it redirect these events to other apps that are subscrived for them. This gem also provides classes that you can use to process the received events too.
Examples¶ ↑
Pure Ruby¶ ↑
require 'active_spy' class Chair include ActiveSpy::Spy watch_method :break! def initialize @broken = false end def break! @broken = true puts 'Crack!!!' end end class ChairEvents < ActiveSpy::Base def before_break! puts 'OMG! You are going to break the chair!' end def after_break! puts 'You broke that chair, man.' end end ActiveSpy::SpyList.activate Chair.new.break!
Rails app¶ ↑
First of all, run the install generator: rails g active_spy:install
. This command will inject gem’s configurations at config/environment.rb
, generate config/active_spy.yml
file and mount active_spy’s engine at config/routes.rb
. You must edit the YAML file to use your own app parameters and optionally change the engine route.
Then, create a ProductEvent
class at RAILS_ROOT/app/events
class ProductEvents < ActiveSpy::Rails::Base end
Declare ActiveSpy’s model_realm
, model_actor
, and watch_model_changes
methods in the model that is being watched:
class User < ActiveRecord::Base belong_to :project belongs_to :project_group model_realm :realm model_actor :my_actor watch_model_changes # ActiveSpy's payload_for method override # # def payload_for(method) # { user: attributes } # end end
You may override payload_for(method)
for more complex use cases. The model_realm :realm
will create a realm attribute accessor for you to use wherever you want, usually inside a controller, to set the realm of the user. The model_actor :my_actor
will create an attribute acessdor for the actor, but will define it using the my_actor
and my_actor=
methods. This allows you to avoid your attributes, methods and relations to be overwritten. Both realm and actor and necesary to be bent to the event runner.
Now, when you can create, update or delete instances of User, a request will be sent to the event_host
and event_port
defined in the configuration YAML file. The body will be filled with a hash like this, as json:
{ type: 'User', # object's class name actor: user.my_actor, # object's actor (who made that action) realm: user.realm, # object's realm action: action # the action executed in the object payload: { user: user.attributes, # a hash with the user attributes inside the 'user' # key } }
Just to remember, you can override #realm
, #actor
and #payload_for(method)
to suit your own needs.
Handling the request received by the event runner¶ ↑
To handle the request received by the event-runner, you need to create a listener class, inheriting from ActiveSpy::Rails::Listener
and named using the watched model’s name plus the Listener
postfix, like this:
class UserListener < ActiveSpy::Rails::Listener end
The default behavior will automatically try to sync the model that was sent with the app own database. If you need a different behavior, you can override the create
, update
and delete
methods to match your needs:
class UserListener < ActiveSpy::Rails::Listener def create(object_type, payload, actor, realm) end def update(object_type, payload, actor, realm) end def destroy(object_type, payload, actor, realm) end end
Contributing to active_spy¶ ↑
-
Check out the latest master to make sure the feature hasn’t been implemented or the bug hasn’t been fixed yet.
-
Check out the issue tracker to make sure someone already hasn’t requested it and/or contributed it.
-
Fork the project.
-
Start a feature/bugfix branch.
-
Commit and push until you are happy with your contribution.
-
Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.
-
Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
Copyright¶ ↑
Copyright © 2014 Douglas Camata. See LICENSE.txt for further details.