Reputation: 5907
I've used CanCan before and it's great, but sometimes I don't need such customizable role management. Sometimes I just need to distinguish between an admin and everyone else. So, I usually just write an :authenticate_admin!
method for the controllers and methods I need to protect.
What I've found a little more complicated is ensuring that users can only manage resources they own. Say, I user can create posts
, I don't want them to be able to update or destroy a post they didn't create. So, I'm curious about how others have gone about handling this in the most DRY way possible.
Here's what I've done, off the top of my head:
In the application controller:
def user_can?(resource_user_id, current_user_id)
return true if current_user.is_admin
return true if resource_user_id == current_user_id
end
Then, in the controller in question, I do something like
before_filter :can_manage_project?, :except => [:new, :create]
and
protected
def can_manage_project?
@project = Project.find(params[:id])
return true if user_can?(@project.user_id, current_user.id)
redirect_to user_path(current_user), :flash => {:error => "Sorry, you're not allowed to do that."}
end
Seems like a lot of code for a relatively simply task. How have you gone about handling this task? I'm sure there's a more elegant solution -- short of using a gem or plugin.
Upvotes: 0
Views: 164
Reputation: 160271
My first thought would be to abstract out a tiny bit and mix in an is_manageable?
method into models via a acts_as_user_manageable
-type doodad. Resource controllers would get a manageable_by_current_user?
filter (I'm not sure how I'd do that automagically yet). is_manageable?
could encapsulate arbitrary rules, so it would be able to handle things like admin flags etc.
I'd have to play a bit to see what implementation I liked the most, but a solution like this seems pretty reasonable, and probably something that a lot of people would dig for projects that don't need the level of control the canonical solutions provide.
Upvotes: 1