Skip to content

Instantly share code, notes, and snippets.

@ryanb
Created November 17, 2009 06:45
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save ryanb/236709 to your computer and use it in GitHub Desktop.
Save ryanb/236709 to your computer and use it in GitHub Desktop.
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, :user_id => user.id if user.role?(:moderator)
if user.role? :author
can :create, Article
can :update, Article, :user_id => user.id
end
end
end
end
class Ability
include CanCan::Ability
def initialize(user)
@user = user || User.new # guest user
if @user.role? :admin
can :manage, :all
else
guest
moderator if @user.role? :moderator
author if @user.role? :author
end
end
def guest
can :read, :all
can :create, Comment
can :update, Comment, :user_id => @user.id
end
def moderator
can :update, Comment
end
def author
can :create, Article
can :update, Article, :user_id => @user.id
end
end
authorization do
role :admin do
has_permission_on [:articles, :comments], :to => [:index, :show, :new, :create, :edit, :update, :destroy]
end
role :guest do
has_permission_on :articles, :to => [:index, :show]
has_permission_on :comments, :to => [:new, :create]
has_permission_on :comments, :to => [:edit, :update] do
if_attribute :user => is { user }
end
end
role :moderator do
includes :guest
has_permission_on :comments, :to => [:edit, :update]
end
role :author do
includes :guest
has_permission_on :articles, :to => [:new, :create]
has_permission_on :articles, :to => [:edit, :update] do
if_attribute :user => is { user }
end
end
end
@tovodeverett
Copy link

I'm a bit confused by the following line in the first file:

      can :update, Comment, :user_id => user.id if user.role?(:moderator)

Perhaps I'm misunderstanding Ruby syntax and operator precedence, but I read that line to say that can :update, Comment, :user_id => user.id executes if user.role?(:moderator) returns true and doesn't execute the first half if the second half is false. That means that moderators can only update Comments they created, and nobody else (except for admins) can modify comments, even if they created them. This seems strange and appears to differ from the behavior declared in cancan_alternative.rb and declarative_authorization.rb, which both seem to implement a rule that guests can modify their own comments, and moderators can modify all comments.

I suspect the desired one-liner might look like the following (although I haven't tested this):

      can :update, Comment, user.role?(:moderator) ? {} : {:user_id => user.id}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment