Skip to content
ryanb edited this page Aug 13, 2010 · 8 revisions

CanCan version 1.3 greatly changes the way nesting controller resources works. It also has support for multiple can definitions in the Ability class.

Nesting Resources

The :nested option no longer exists on load_and_authorize_resource. You should now use the :through option and define the load_resource option separately. For example, you will need to change this.

class ProductsController < ApplicationController
  load_and_authorize_resource :nested => :category
end

To this.

class ProductsController < ApplicationController
  load_resource :category
  load_and_authorize_resource :product, :through => :category
end

This way deep nesting is fully supported and you can pass as many options to each load/authorize_resource call. If you want to do authorization on the parent resource that is now supported as well.

class ProductsController < ApplicationController
  load_and_authorize_resource :category
  load_and_authorize_resource :product, :through => :category
end

This will ensure the user can :read the category which is loaded for each action. See Nested Resources for more information.

Multiple can definitions

It is now possible to specify multiple can and cannot definitions with hashes and have it properly translate to a single SQL query.

# in Ability
can :manage, User, :id => 1
can :manage, User, :manager_id => 1
cannot :manage, User, :self_managed => true
    #   query(:manage, User).conditions # => "not (self_managed = 't') AND ((manager_id = 1) OR (id = 1))"

When using accessible_by in the controller it will translate to SQL conditions that look like this.

not (self_managed = 't') AND ((manager_id = 1) OR (id = 1))

Special thanks to funny-falcon for this feature.