#192 Authorization with CanCan
Dec 14, 2009 | 15 minutes | Authorization, Plugins
CanCan is a simple authorization plugin that offers a lot of flexibility. See how to use it in this episode.
- Download:
- source codeProject Files in Zip (107 KB)
- mp4Full Size H.264 Video (26.1 MB)
- m4vSmaller H.264 Video (17.3 MB)
- webmFull Size VP8 Video (43.9 MB)
- ogvFull Size Theora Video (36.9 MB)
Resources
- CanCan
- Episode 160: Authlogic
- Episode 188: Declarative Authorization
- Episode 189: Embedded Association
- Full Episode Source Code
bash
sudo rake gems:install
sudo rake gems:install
config/environment.rb
config.gem "cancan"
config.gem "cancan"
models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user
if user.role? :admin
can :manage, :all
else
can :read, :all
can :create, Comment
can :update, Comment do |comment|
comment.try(:user) == user || user.role?(:moderator)
end
if user.role?(:author)
can :create, Article
can :update, Article do |article|
article.try(:user) == user
end
end
end
end
end
class Ability include CanCan::Ability def initialize(user) user ||= User.new # guest user if user.role? :admin can :manage, :all else can :read, :all can :create, Comment can :update, Comment do |comment| comment.try(:user) == user || user.role?(:moderator) end if user.role?(:author) can :create, Article can :update, Article do |article| article.try(:user) == user end end end end end
application_controller.rb
rescue_from CanCan::AccessDenied do |exception|
flash[:error] = "Access denied."
redirect_to root_url
end
rescue_from CanCan::AccessDenied do |exception| flash[:error] = "Access denied." redirect_to root_url end
articles_controller.rb
load_and_authorize_resource
# comments_controller.rb possibility
load_and_authorize_resource :nested => :article
load_and_authorize_resource # comments_controller.rb possibility load_and_authorize_resource :nested => :article
articles/show.html.erb
<p>
<% if can? :update, @article %>
<%= link_to "Edit", edit_article_path(@article) %> |
<% end %>
<% if can? :destroy, @article %>
<%= link_to "Destroy", @article, :method => :delete, :confirm => "Are you sure?" %> |
<% end %>
<%= link_to "Back to Articles", articles_path %>
</p>
...
<p>
<% if can? :update, comment %>
<%= link_to "Edit", edit_comment_path(comment) %>
<% end %>
<% if can? :destroy, comment %>
| <%= link_to "Destroy", comment, :method => :delete, :confirm => "Are you sure?" %>
<% end %>
</p>
<p> <% if can? :update, @article %> <%= link_to "Edit", edit_article_path(@article) %> | <% end %> <% if can? :destroy, @article %> <%= link_to "Destroy", @article, :method => :delete, :confirm => "Are you sure?" %> | <% end %> <%= link_to "Back to Articles", articles_path %> </p> ... <p> <% if can? :update, comment %> <%= link_to "Edit", edit_comment_path(comment) %> <% end %> <% if can? :destroy, comment %> | <%= link_to "Destroy", comment, :method => :delete, :confirm => "Are you sure?" %> <% end %> </p>
articles/index.html.erb
<% if can? :create, Article %>
<p><%= link_to "New Article", new_article_path %></p>
<% end %>
<% if can? :create, Article %> <p><%= link_to "New Article", new_article_path %></p> <% end %>

