Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you deal with a :create permission in cancan that's defined by the parent object?

Tags:

cancan

Let's say you're writing the software for Blogger.

Each user can create a blog post only if they are the owner of the blog. CanCan would normally define an ability check in this circumstance as:

user.can? :create, Post

However the user can only create the post if they are the owner of the current blog and there's no way to reference the current blog using only its classname. What I really need to be able to do is:

user.can? :create, Post, @current_blog

such that in the cancan definitions I can say

can :create, Post do |post, blog|
  user == blog.owner
end

Is that possible or am I confused in how I'm approaching this?

like image 501
Peter Nixey Avatar asked Feb 21 '12 09:02

Peter Nixey


1 Answers

Define an ability based on the parent of the current object:

can :create, Post, :blog => { :user => user }

This will make sure the current user can only create a new Post record for a blog that they are an owner of.

  • uses Post.blog_id to find parent Blog record
  • compares Blog.user_id field to current_user.id field

Also make sure that you are using a :through declaration when loading and authorizing your Post resource, so CanCan knows who the parent record is.

PostsController:

load_and_authorize_resource :through => :blog

See the CanCan wiki on GitHub for more detail.

like image 58
dlehman Avatar answered Oct 09 '22 10:10

dlehman