How can I allow a user to only update reviews they have written using cancan?
I've been following through Ryan Bates' railscast on using cancan but am stumped as to why checking whether a user has written a review and then allowing them to edit it if they have, wont work for me.
heres the code I have:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.role == "admin"
can :manage, :all
else
can :read, :all
if user.role == "author"
can :create, Review
can :update, Review do |review|
开发者_如何学C review.try(:user) == user
end
end
end
end
end
I want authors to only be able to update the reviews they have written, all the other abilities work fine but at the minute an author can update reviews written by everyone, what am I missing here?
Im using the ability to decide whether or not to display the edit link in the review partial:
<% if can? :update, Review %>
testing
<% end %>
Thanks for any help!
In your view you should write something like
<% if can? :update, @review %>
testing
<% end %>
So pass in the actual review-object, instead of just the class.
Try:
review.user_id == user.id
Instead of:
review.try(:user) == user
You're comparing two different instances of the same user. This probably is using user.object_id for the comparison. Rails 3.1 fixes this by using an Identity Map for ActiveRecord.
To confirm:
user.find(1) == user.find(1)
I would avoid using a block for this use case, and use CanCan's attribute hash approach instead:
if user.role == "author"
can :create, Review
can :update, Review, :user_id => user.id
end
This will compare based on the user ID rather than the user object itself.
精彩评论