2

Application I am working has different user roles client, project manager and super user and on landing page they can search for Articles and there is an advanced filter to filter out records after search. Like: Filter by Author.

I want to hide advance filter for client, for that I want to define ability using cancancan.

Currently I am doing it with model methods. These methods return true and false on the basis of user type.

client?
project_manager?
super_user?

Current Code:

<% unless current_user.client? %>
   <%=link_to "Advance Search", "#" %>
<%end%>

I want to remove this and use cancancan instead of this.

<%if can? :filter, Article %>
  <%=link_to "Advance Search", "#" %>
<%end%>

For this I tried

cannot :filter, Article if user.client?

But this is restricting all users to filter.

halfer
  • 19,824
  • 17
  • 99
  • 186
Pardeep Dhingra
  • 3,916
  • 7
  • 30
  • 56
  • @pradeepDhingra. cannot :filter, Article if user.client? this line should restrict only the client can you please tell us how it is restricting all users? – Prabhakar Jun 16 '15 at 12:24
  • @Prabhakar its not showing Advance Search link for all users..That's my question, it should not restrict all users. Earlier it was showing link for other users except client, but after applying cancan its restricting all users.. – Pardeep Dhingra Jun 16 '15 at 12:26

3 Answers3

1

You need to declare a can rule to actually allow users to :filter.

can :filter, Article do |article|
  !user.client?
end

Or

unless user.client?
  can :filter, Article
end

An example of using cannot:

can :friend, User

cannot :friend, User do |other_user|
  other_user.blocks?(user)
end
max
  • 96,212
  • 14
  • 104
  • 165
  • `unless user.client? can :filter, Article end` This is working but why not to use `cannot`. – Pardeep Dhingra Jun 16 '15 at 12:29
  • Because `cannot` does not actually allow any user to do ANYTHING. It just declares something the user cannot do. – max Jun 16 '15 at 12:31
  • I think you are a bit confused about how the conditional works, `cannot :filter, Article if user.client?` Runs `cannot :filter, Article` only if the predicate if the `if user.client?` is met. It does not do the inverse action of creating a `can` permission. Its just like `puts 'hello' if user.client? ` – max Jun 16 '15 at 12:34
  • `cannot` can be used if you need to have a specific rule where users should not be authorized to perform an action. You can use it instead of having a bunch of conditions in the `can` declaration. – max Jun 16 '15 at 12:37
  • In my view multiple parts of view are restricted for different user roles. Filter is one of them.What would be your suggestion to improve readability and maintainability ? Like filter i should create `can` ability for all different sections..or any other suggestion.. – Pardeep Dhingra Jun 16 '15 at 12:52
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/80671/discussion-between-maxcal-and-pardeep-dhingra). – max Jun 16 '15 at 12:52
0

Change the role a bit as following

can :filter, Article unless user.client?

You can read about custom role definition for cancan from here

Rokibul Hasan
  • 4,078
  • 2
  • 19
  • 30
-1

Can you try this

# in models/user.rb
def is?(role)
  roles.include?(role.to_s)
end

# in models/articles.rb
can :filter, :all if user.is? :client || :super_user

The above filter will make only the client or super_user can filter the stuff.

Prabhakar
  • 6,458
  • 2
  • 40
  • 51
  • Did you even read the question? The OP has not specified that he is using any roles or a role library. – max Jun 16 '15 at 12:39