Module: CanCan::ControllerAdditions

Defined in:
lib/cancan/controller_additions.rb

Overview

This module is automatically included into all controllers. It also makes the “can?” and “cannot?” methods available to all views.

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



290
291
292
293
# File 'lib/cancan/controller_additions.rb', line 290

def self.included(base)
  base.extend ClassMethods
  base.helper_method :can?, :cannot?, :current_ability
end

Instance Method Details

#authorize!(*args) ⇒ Object

Raises a CanCan::AccessDenied exception if the current_ability cannot perform the given action. This is usually called in a controller action or before filter to perform the authorization.

def show
  @article = Article.find(params[:id])
  authorize! :read, @article
end

A :message option can be passed to specify a different message.

authorize! :read, @article, :message => "Not authorized to read #{@article.name}"

You can also use I18n to customize the message. Action aliases defined in Ability work here.

en:
  unauthorized:
    manage:
      all: "Not authorized to %{action} %{subject}."
      user: "Not allowed to manage other user accounts."
    update:
      project: "Not allowed to update this project."

You can rescue from the exception in the controller to customize how unauthorized access is displayed to the user.

class ApplicationController < ActionController::Base
  rescue_from CanCan::AccessDenied do |exception|
    redirect_to root_url, :alert => exception.message
  end
end

See the CanCan::AccessDenied exception for more details on working with the exception.

See the load_and_authorize_resource method to automatically add the authorize! behavior to the default RESTful actions.



331
332
333
334
# File 'lib/cancan/controller_additions.rb', line 331

def authorize!(*args)
  @_authorized = true
  current_ability.authorize!(*args)
end

#can?(*args) ⇒ Boolean

Use in the controller or view to check the user’s permission for a given action and object.

can? :destroy, @project

You can also pass the class instead of an instance (if you don’t have one handy).

<% if can? :create, Project %>
  <%= link_to "New Project", new_project_path %>
<% end %>

If it’s a nested resource, you can pass the parent instance in a hash. This way it will check conditions which reach through that association.

<% if can? :create, @category => Project %>
  <%= link_to "New Project", new_project_path %>
<% end %>

This simply calls “can?” on the current_ability. See Ability#can?.

Returns:

  • (Boolean)


374
375
376
# File 'lib/cancan/controller_additions.rb', line 374

def can?(*args)
  current_ability.can?(*args)
end

#cannot?(*args) ⇒ Boolean

Convenience method which works the same as “can?” but returns the opposite value.

cannot? :destroy, @project

Returns:

  • (Boolean)


382
383
384
# File 'lib/cancan/controller_additions.rb', line 382

def cannot?(*args)
  current_ability.cannot?(*args)
end

#current_abilityObject

Creates and returns the current user’s ability and caches it. If you want to override how the Ability is defined then this is the place. Just define the method in the controller to change behavior.

def current_ability
  # instead of Ability.new(current_user)
  @current_ability ||= UserAbility.new()
end

Notice it is important to cache the ability object so it is not recreated every time.



351
352
353
# File 'lib/cancan/controller_additions.rb', line 351

def current_ability
  @current_ability ||= ::Ability.new(current_user)
end

#unauthorized!(message = nil) ⇒ Object



336
337
338
# File 'lib/cancan/controller_additions.rb', line 336

def unauthorized!(message = nil)
  raise ImplementationRemoved, "The unauthorized! method has been removed from CanCan, use authorize! instead."
end