I've been going through the railscast on using the cancan gem but am stuck on how to only allow a user to visit their own show page.
My code looks like this:
Ability model
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|
review.try(:user) == user
end
can :update, User do |user|
user.try(:current_user) == current_user
end
end
if user.role == "owner"
can :update, Venue
end
end
end
end
User controller
class UsersController < ApplicationController
load_and_authorize_resource
end
A user (author) can only update their own reviews, but can currently view all users show pages by altering the URL.
What am I missing here?
Constraints can be passed right in your ability class, even easier than the way you're trying. I'm sure this is missing some abilities you're looking to have, but this should get you started. I'm assuming Reviews :belong_to
Users with a foreign key of :user_id
. It also looks like you need some similar kind of constraint for Venues, but you didn't have it in your code so I didn't put it in this.
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.role == "admin"
can :manage, :all
elsif user.role == "author"
can :create, Review
can :update, Review, :user_id => user.id
can [:show, :update], User, :id => user.id
elsif user.role == "owner"
can :update, Venue
can [:show, :update], User, :id => user.id
else
can [:show, :update], User, :id => user.id
end
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With