CanCan - How to allow users to update and delete only their own objects
Asked Answered
E

2

8

I've started a Rails application with Devise and CanCan. I have users which has a one-to-many relationship to articles. I'm new to CanCan, here's what I'm planning to do:

Admin

  • can do any action on articles

Logged in user

  • can read and create articles
  • can edit and destroy his own articles

Guest user

  • can read articles

But I'm having trouble understanding the syntax of CanCan. I understand it would be something like this.

def initialize(user)
  user ||= User.new
  if user.admin?
    can :manage, Article
  else
    can :read, Article
  end
end

But this is just for the admin and guest user, I'm not sure how to differentiate a guest user from a logged in user because it creates a new User object when user is empty. I've seen that the code should be something like this can [:edit, :destroy], Article, :user_id => user.id, but I'm not sure how this would fit in the initialize method.

And one last question, if I only define a can :read, Article on guests, would it block the other actions such as create and update, like white listing the read action?

Any help would be appreciated. Thanks a lot!

Entoil answered 1/8, 2012 at 6:20 Comment(0)
E
22

Here's what I did:

In ability.rb

def initialize(user)
  if user.nil?
    can :read, Article
  elsif user.admin?
    can :manage, Article
  else
    can [:read, :create], Article
    can [:update, :destroy], Article, :user_id => user.id
  end
end

And for displaying the links, I've used this:

- if can? :read, Article
  = link_to 'Show', article
- if can? :create, Article
  = link_to 'New Article', new_article_path
- if can? :update, article
  = link_to 'Edit', edit_article_path(article)
- if can? :destroy, article
  = link_to 'Destroy', article, method: :delete, data: { confirm: 'Are you sure?' }

And it seems to be working now, not sure if that's the best way though.

Entoil answered 1/8, 2012 at 7:25 Comment(2)
The view does not looks good, but it is not related to the question topic, which seems covered well in your ability.rb.Treponema
I'm use self-made helpers, such as link_to_edit, link_to_destroy, etc. My helpers includes call to can?(), so there is no need to put logic inside views.Treponema
T
8

You can pass hash of conditions:

can :manage, Article, :user_id => user.id

Look at https://github.com/ryanb/cancan/wiki/defining-abilities for details.

Treponema answered 1/8, 2012 at 7:25 Comment(1)
I'm added this comment same time @mumble edited question, and for now question includes answer.Treponema

© 2022 - 2024 — McMap. All rights reserved.