module Guacamole::Callbacks

Define callbacks for different life cycle events of a model

Callbacks in Guacamole are defined in dedicated classes only. There will be no interface to implement them in the model or the collection context. This was done due to the nature of the data mapper pattern:

* The model doesn't know anything about the database thus defining persistence related callbacks (i.e. `before_create`)
  would weaken this separation.
* Validation happens in the context of the model and thus defining all callbacks in the collection would still
  be somewhat awkward.

Due to those reasons Guacamole employs the concept of **external callbacks**. Just define a class and include the ‘Guacamole::Callbacks` module and you can define all kinds of callbacks. Under the hood `ActiveModel::Callbacks` is used to provide the callback execution functionality.

@note Wether you define a callback class for your model or not, internally there always will be a callback.

Since maintaining the time stamp attributes of your models are implemented as callbacks as well your callback class will have those methods included.

Binding a callback class to a model will happen in the ‘Model.callbacks` method.

Each callback class will be instantiated with the appropriate model instance. That instance is accessible through the ‘object` method.

@example Define a callback to hash the password prior creation

class UserCallbacks
  include Guacamole::Callbacks

  before_create :encrypt_password

  def encrypt_password
    object.encrypted_password = BCrypt::Password.create(object.password)
  end
end

@!method self.before_validate(method_name)

Registers a method to be run before the validation will happen

@param [Symbol] method_name The name of the method to be executed
@api public

@!method self.around_validate(method_name)

Registers a method to be run before and after the validation will happen.

@param [Symbol] method_name The name of the method to be executed
@api public
@note You must `yield` at some point in the method.

@!method self.after_validate(method_name)

Registers a method to be run after the validation happened

@param [Symbol] method_name The name of the method to be executed
@api public

@!method self.before_save(method_name)

Registers a method to be run before the collection class saves the model

Saving a model will always happen, no matter if the model will be created or
updated.

@param [Symbol] method_name The name of the method to be executed
@api public

@!method self.around_save(method_name)

Registers a method to be run before and after saving the model

Saving a model will always happen, no matter if the model will be created or
updated.

@param [Symbol] method_name The name of the method to be executed
@api public
@note You must `yield` at some point in the method.

@!method self.after_save(method_name)

Registers a method to be run after the collection class has saved the model

Saving a model will always happen, no matter if the model will be created or
updated.

@param [Symbol] method_name The name of the method to be executed
@api public

@!method self.before_create(method_name)

Registers a method to be run before initially creating the model in the database

@param [Symbol] method_name The name of the method to be executed
@api public

@!method self.around_create(method_name)

Registers a method to be run before and after creating the model

@param [Symbol] method_name The name of the method to be executed
@api public
@note You must `yield` at some point in the method.

@!method self.after_create(method_name)

Registers a method to be run after the creation of the model

@param [Symbol] method_name The name of the method to be executed
@api public

@!method self.before_update(method_name)

Registers a method to be run before updating the model

@param [Symbol] method_name The name of the method to be executed
@api public

@!method self.around_update(method_name)

Registers a method to be run before and after updating the model

@param [Symbol] method_name The name of the method to be executed
@api public
@note You must `yield` at some point in the method.

@!method self.after_update(method_name)

Registers a method to be run after the model has been updated

@param [Symbol] method_name The name of the method to be executed
@api public

@!method self.before_delete(method_name)

Registers a method to be run before deleting the model

@param [Symbol] method_name The name of the method to be executed
@api public

@!method self.around_delete(method_name)

Registers a method to be run before and after the deletion

@param [Symbol] method_name The name of the method to be executed
@api public
@note You must `yield` at some point in the method.

@!method self.after_delete(method_name)

Registers a method to be run after the deletion of the model has happened

@param [Symbol] method_name The name of the method to be executed
@api public

Public Class Methods

callbacks_for(model) click to toggle source

Retrieve the callback instance for the given model

@api private @params [Model] model The model instance for which callbacks must be executed @return [Callbacks] A callback instance with the given model accessible via ‘object`

# File lib/guacamole/callbacks.rb, line 219
def callbacks_for(model)
  CallbackProxy.new registry[model.class].new(model)
end
new(model_instance) click to toggle source

Create a new callback instance with the given model instance

@param [Model] model_instance The model instance the callbacks should be executed for

# File lib/guacamole/callbacks.rb, line 235
def initialize(model_instance)
  @object = model_instance
end
register_callback(model_class, callback_class) click to toggle source

Register a callback class to be used with the model

@api private @param [Model] model_class The class of a model @param [Callbacks] callback_class The class of the callbacks

# File lib/guacamole/callbacks.rb, line 210
def register_callback(model_class, callback_class)
  registry[model_class] = callback_class
end
registry() click to toggle source

The internal storage of the callback-model pairs

@api private @return [Hash] A hash with the default set to the ‘DefaultCallback`

# File lib/guacamole/callbacks.rb, line 227
def registry
  @registry ||= Hash.new(DefaultCallback)
end

Public Instance Methods

add_create_timestamps() click to toggle source

Sets ‘created_at` and `updated_at` to `Time.now`

# File lib/guacamole/callbacks.rb, line 248
def add_create_timestamps
  object.created_at = Time.now
  update_updated_at_timestamp
end
object() click to toggle source

Provides access to the model instance.

@retun [Model] A model instance @api public

# File lib/guacamole/callbacks.rb, line 243
def object
  @object
end
update_updated_at_timestamp() click to toggle source

Sets ‘updated_at` to `Time.now`

# File lib/guacamole/callbacks.rb, line 254
def update_updated_at_timestamp
  object.updated_at = Time.now
end