kristianmandrup edited this page Nov 11, 2011 · 5 revisions

CanTango is split up into a few major logical units that we call engines. Currently CanTango comes with these engines:

Note that the Cache engine is not a "real" engine, as it doesn't subclass CanTango::Engine and isn't executed.

You can configure each engine to some extent and even replace the engine entirely with your own custom implementation by using the #factory config method. See Configuration for more details. CanTango also lets you create and register your own engine into the mix.



Any CanTango engine can be configured and examined with the engine config API as demonstrated here:

CanTango.config.engine(:permit) do |engine|
  puts engine.modes
  engine.mode = :cache
  engine.set :on
  engine.reset! # state to default value
  puts "ON" if engine.on?
  puts "OFF" if engine.off?

Note that control of caching is now done by setting execution modes and not by setting the caching engine directly (like it used to).

Engine Registration and configuration

CanTango lets you register engines and configure the execution order in the Ability execution flow.

Engines Config API

  • active - list of symbols for all active engines (that respond true to on?)

Engine Registration API

  • register= hash
  • registered
  • unregister *keys

Engine Execution order API

  • execution_order= *names
  • execution_order
  • execute_before existing_name, name
  • execute_after existing_name, name

Example engines registration and configuration:

CanTango.config.engines do |engines|
  engines.register :my_engine => MyCoolEngine, :performance => PeformanceTool
  engines.execution_order :permit, :my_engine, :permission
  engines.execute_before :permit, :performance_tool  
  engines.execute_last :performance_tool

The CanTango::PermitEngine and CanTango::PermissionEngine are classes that both implement the generic CanTango::Engine class.

Creating Custom engines

Creating a custom CanTango engine is not too difficult. Start by subclassing the base CanTango::Engine class.

class MyCustomEngine < CanTango::Engine

This will automatically register the engine with CanTango, similar to Users, Accounts and Permits, using an inherited hook on CanTango::Engine.

Now implement the CanTango Engine API. You need an #initialize method that takes an ability and a #permit_rules method that populates the rules set.

class MyCustomEngine < CanTango::Engine
  def initialize ability

  def permit_rules
    rules << my_rules if !my_rules.blank?

  def engine_name

  def valid?
    return false if !valid_mode?

  def key_method_names

Currently you also need an #engine_name method which returns the name of the engine. In the future this name will be extracted from the class name unless this method is specified.

The #valid? method should return true only if this engine is valid for the current context (fx the cache mode).

The #key_method_names should return an array of methods to be called on the ability candidate to be used for calculating the cache key for this engine.