Search code examples
ruby-on-railsruby-on-rails-3ruby-on-rails-4cancan

How can I enable admin to destroy the record when using CanCan?


My current code is just like this.
Only the user who posted can destroy his own records.
But I want to enable admin(user.id=1) to delete all the records.

How can I change this? also view? any smart way?

/models/ability.rb

def initialize(user)
    if user
        can :read, :all 
        can [:create, :destroy], Comment, {:user_id => user.id}
        can [:destroy], Comment, {:commentable_id => user.id, :commentable_type => user.class.name}
        can [:create, :update], Community, {:user_id => user.id}
    else
        can :read, :all 
    end
end

View

<%= link_to 'x', polymorphic_path([@user, comment]),
    :data => { :confirm => 'Do you want to delete?' },  
    :method => :delete, :disable_with => 'Deleting', 
    :remote => true, 
    :class => 'close'
if current_user && current_user.id == comment.user_id || current_user && current_user.id == comment.commentable_id %>

Solution

  • Here is what you need. BTW it is bad idea to use user.id == 1 to check for admin rights, probably better solution is to add boolean admin field to User model. If you don't want to do it, you can replace if user.admin? with if user.id == 1.

    def initialize(user)
      guest_ability
      user_ability(user) if user
      admin_ability if user.admin? # or `if user.id == 1` if you don't want to add `admin` field
    end
    
    private
    
    def admin_ability(admin)
      can [:destroy], Comment
    end
    
    def user_ability(user)
      can :read, :all 
      can [:create, :destroy], Comment, { :user_id => user.id }
      can [:destroy], Comment, { :commentable_id => user.id, :commentable_type => user.class.name }
      can [:create, :update], Community, { :user_id => user.id }
    end
    
    def guest_ability
      can :read, :all
    end
    

    In your view:

    <% if can? :destroy, comment %>
      <%= link_to 'x', polymorphic_path([@user, comment]),
            :data => { :confirm => 'Do you want to delete?' },  
            :method => :delete, :disable_with => 'Deleting', 
            :remote => true, 
            :class => 'close' %>
    <% end %>