0
votes

How do I grant permission to edit/ destroy links on a by-user basis in the user index of rails?

I'm using Rails3, Devise and CanCan to define role based abilities.

I'd like the current user to be able to see and access a link to edit/delete their profile in the user index page. They should not be able to see or access these links for all other users.

I've set up the following in the index view:

<% if can? :update, @user %>
     <%= link_to 'Edit', edit_user_registration_path(@user) %> | 
<% end %>

And in abilities.rb

def initialize(user) 
    can :update, User, :id => user.id
    if user.role? :super_admin
       can :manage, :all
    end
end

My superadmin can see and edit links for all users in the index.

My user can see links for no one, not even themselves.

The more I read around this the more confused I get, what with devise, cancan and the user model all playing a role.

I'd appreciate some confirmation that I'm on the right track, and would be grateful for any pointers towards useful information that would help me understand this.

Many thanks

4

4 Answers

3
votes

In abilities.rb

can :manage, User do |u|
  u.id == user.id
end

if you want to go by ID.

Your view looks good to me.

2
votes

This is a total blind shot, but maybe it works:

<% if can?(:update, @user) || @user==current_user %>
     <%= link_to 'Edit', edit_user_registration_path(@user) %> | 
<% end %>

Replace current_user with whatever holds the currently logged in user.

2
votes

Try this and see if it works (if you are still having this issue.) I don't think your regular user should be outside the if statement.(change the variable as you see fit.)

def initialize(user)
 user ||= User.new #guest user
  if user.role? :super_admin
   can :manage, :all
  else
   can :update, User, :id => user.id
   can :read, :all # you can try it with this line removed at first
  end
end
0
votes

You are confused yourself and this way, you are making it even more difficult for you.
At one point you are saying,

I'd like the current user to be able to see and access a link to edit/delete their profile in the user index page. They should not be able to see or access these links for all other users.

On the other hand,

My superadmin can see and edit links for all users in the index. My user can see links for no one, not even themselves

I understand what you are trying to say. You want:

  1. SuperAdmin can see all links for anything, and
  2. A user can only see links for himself, and no one else, and that too, only the edit and update profile or even you could add the delete account links. But the main concern is that a user can only see links on his/her profile and no where else.

Some points to consider:

Did you assign the abilities properly in the Ability class. Look for something like this in your code, and see if it works in the console.

def current_ability
  @current_ability ||= Ability.new(current_user)
end

If yes, move on to this part:

can :manage, User do |user|
  user == current_user #Assign the abilities for the user, here only,
# no need to match the id for each view in the link.
end

If it still doesn't work, take some time off, go through these links again, I know it can be really confusing, but believe me you are quite close.

Wiki - Defining-Abilities
Wiki - Changing-Defaults

When you get there, would you like to share with me, your approach of how you did the whole thing. I would love to hear from you.