hellion
hellion

Reputation: 4830

The different ways of using CanCan abilities

I have four scenarios I want to get some feedback on so I can better understand how CanCan works with abilities.

1 - Is using the object from an iteration acceptable for passing the model to CanCan. It seems to work fine. It seems this will define a very specific ability from the object passed.

 @users.each do |user|
    link_to user.name, user_path(user) if can? :edit, user

2 - @user is not a variable that is set in the controller. This, I'm assuming, is the same as #1 since load_and_authorize_resource creates the @user instance.

 @users.each do |user|
    link_to user.name, user_path(user) if can? :edit, @user

But, what about when an instance variable exists in a view that is not related to the current model and is not deliberately set in the controller. For instance the following inside the show user page when the @account instance is NOT set in the show action. How does CanCan use @account when it shouldnt know what it even is?

  link_to "view user account", account_path(1) if can? :read, @account

3 - What about defining the ability using the model? I assume this is a very broad "can edit users" ability...when would you ever use this?

 @users.each do |user|
    link_to user.name, user_path(user) if can? :edit, User

4 - Using an association. Doesn't break the page...but, Im not sure if it is working as expected.

 @users.each do |user|
    link_to "view user account", account_path(1) if can? :read, user.account

Upvotes: 2

Views: 1268

Answers (1)

Ryan Bigg
Ryan Bigg

Reputation: 107728

Oooh, a multi-part question.

Case #1 and #2

These two are nearly identical. The difference is that the @user variable is being set up in your controller before hand with the load_and_authorize_call or some other filter that runs before your actions.

This is useful if you want to check permissions on a single object, i.e. a user can only edit their own record.

For the end of case #2:

You will need to ensure that the variables are set within the controller before you can access them within your controller or view to do permission checking. Same as if you wanted to access them in other instances that have nothing to do with permission checking.

Case #3

Mainly used in cases where a user can edit all objects of a particular class.

This is useful if you want a user to edit all objects of a particular class, i.e. an admin can edit all user's details

Case #4

Using an association will grab that record out and pass it to CanCan, just like using if can? :read, user would. Not really any different to Case #1.

Upvotes: 1

Related Questions