Implementation of Pre and Post Hooks
Hooks in Jellyfish are implemented through ActiveSupport::Notifications which are part of Rails. Each controller in Jellyfish inherits a private
post_hook method from the Rails Application Controller.
class ApplicationController < ActionController::Base ... private ... def pre_hook ActiveSupport::Notifications.instrument(controller_name + '#' + action_name + '/pre_hook', params) end def post_hook ActiveSupport::Notifications.instrument(controller_name + '#' + action_name + '/post_hook', params) end ... end
How to Instrument Pre and Post Hooks
To instrument a Pre or Post hook from a controller, add the corresponding
before_action :pre_hook or
after_action :post_hook as follows:
class SessionsController < Devise::SessionsController before_action :pre_hook after_action :post_hook ... end
This will instrument Pre and Post hook events to subscribers when any route in the controller is triggered.
How to Subscribe to a Pre or Post Hook (from API)
You can subscribe to instrumented hooks in Jellyfish by adding them under the
For example, we could add a new file named
subscribers.rb to our initializers directory with the following content:
... ActiveSupport::Notifications.subscribe('sessions#create/pre_hook') do |*args| # SOME PRE HOOK ACTION end ActiveSupport::Notifications.subscribe('sessions#create/post_hook') do |*args| # SOME POST HOOK ACTION end ...
Rails will then automatically subscribe to the
sessions#create/post_hook events upon
To see which events correspond to which routes, you can run
rake routes from the terminal:
$ rake routes Prefix Verb URI Pattern Controller#Action staff_session POST /staff/sign_in(.:format) sessions#create destroy_staff_session DELETE /staff/sign_out(.:format) sessions#destroy ``` In the above example, we see that the `staff/sign_in` and `staff/sign_out` are mapped to the `sessions#create` and `sessions#destroy` routes respectively. Using that information, we can subscribe to Pre and Post hooks using the following naming convention: ```ruby controller_name + '#' + action_name + '/pre_hook' # FOR A PRE HOOK EVENT controller_name + '#' + action_name + '/post_hook' # FOR A POST HOOK EVENT
ActiveSupport::Notifications provides access to the following attributes which we can use from within our hook subscription:
... ActiveSupport::Notifications.subscribe('sessions#create/pre_hook') do |*args| @name = args # => String, name of the event @start = args # => Time, when the instrumented block started execution @finish = args # => Time, when the instrumented block ended execution @id = args # => String, unique ID for this notification @payload = args # => Params Hash - custom data specific to route that triggered event ... # USER DEFINED CODE ... end ...
How to Subscribe to a Pre or Post Hook (from a module)
Subscribing to a Pre or Post hook from a module should be analogous to subscribing from within API. Make sure that the module includes Rails and define your subscriptions in a way that will get picked up by Rails on initialization.