Skip to content
kristianmandrup edited this page Nov 8, 2011 · 1 revision

In CanTango the Ability is by default divided into the following 3 components:

  • AbilityExecutor
  • Ability (no-cache mode)
  • CachedAbility (cache mode)

Ability execution

The Ability for a given candidate can be executed in the following modes:

  • :cache
  • :no_cache
  • :both (:cache and :no cache, in succession)

For each of the modes, the AbilityExecutor is run and depending on the mode configuration, one or both of Ability and CachedAbility are run and the rules merged into the resulting ruleset.

Example (cache only)

CanTango.configure do |config|
  config.ability.mode = :cache
end

You can also configure each of the permit/permission engines according to which modes they should participate in. Here an example configuration:

CanTango.configure do |config|
  config.engine(:permission).mode = :cache
  config.engine(:permits).mode = :both
  config.engine(:user_ac).mode = :no_cache
end

Currently, only the Permits engine supports the :both mode. The permission and user_ac engines can be run in either :cache or :no_cache mode.

To see the modes currently configured: CanTango.config.engine(:permission).modes or for the ability execution as a whole CanTango.config.ability.modes

By letting you configure the execution mode you should have all the control you need!

Ability rules

For simple scenarios you can choose to define your rules directly in the Ability similar to the approach in CanCan. The rules should be specified in the #permit_rules method, NOT in the #initialize method.

No-Cache Ability

class CanTango::Ability
  def permit_rules
    can :read, Article
  end
end

Cached Ability

class CanTango::CachedAbility
  def permit_rules
    can :read, Article
  end
end

This approach is useful if you have simple Access Control requirements but you still want to take advantage of core CanTango features such as rules caching.

You will likely plan to later use the various engines such as the Permit engine and Permission engine. It should be easy to later migrate the rules and put them into various engines to best suit your requirements.

Customizing Ability

For some cases, you might want to create a Custom Ability. This can be done as follows:

class MyCustomAbility < CanTango::Ability
  def initialize candidate, options = {}
    # super
    # custom logic
  end
end

Then configure your own Ability factory to use your custom Ability.

Cantango.config.ability do |ability|
  ability.factory Proc.new {|candidate, options| MyCustomAbility.new candidate, options }
end

Note: This feature is currently used (in the specs) for performance testing of CanTango!

In the near future, we aim to allow this approach for both the AbilityExecutor, CachedAbility and Ability (:no_cache mode).