Cancan Status

I use CanCan in a project to manage different role levels for each object for each project. I'm doing it:

# encoding: utf-8 class Ability include CanCan::Ability def initialize(user) user ||= User.new if user.is_admin == true can :manage, :all else can :read, :all Project.all.each do |project| current_role_name = user.roles.find_by_project_id(project.id).role_name.name if current_role_name.eql?'Auteur senior' can :manage, [Project, Introduction, Abstract, Text, Conclusion, Asset, Attachment], :project_id => project.id elsif current_role_name.eql?'Auteur junior' can :manage, [Introduction, Abstract, Attachment], :project_id => project.id can :update, Text, :project_id => project.id, :user_level => current_role_name can :manage, [Asset], :project_id => project.id, :user_level => current_role_name elsif current_role_name.eql?'Équipe phylogéniste' can :manage, [Attachment], :project_id => project.id can :manage, [Text, Asset], :project_id => project.id, :user_level => current_role_name end end end end end 

This works when I check the role_name username, but after I want to use a condition like this:

 can :update, Text, :project_id => project.id, :user_level => current_role_name 

The condition has no effect. How can I make it work?

0
source share
3 answers

Finally, I found a solution:

In the corresponding controller, I replaced authorize_resource with load_and_authorize_resource and that it is.

+1
source

What am I doing:

1- Defining roles in my User class and their impact on users.

 class User # CanCan roles ( see Users::Ability) ROLES = %w[auteur_senior auteur_junior] def roles=(roles) self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.sum end def roles ROLES.reject do |r| ((roles_mask || 0) & 2**ROLES.index(r)).zero? end end def is?(role) roles.include?(role.to_s) end # define all bollean set/get methods for roles ROLES.each do |r| define_method "is_#{r}" do self.roles += [r] self end define_method "is_#{r}?" do roles.include?(r) self end end end 

2 - In the ability to influence the capabilities of each role

 class Ability include CanCan::Ability def initialize(user) @user = user || User.new # for guest @user.roles.each { |role| send(role) } end def auteur_junior can :manage, [Introduction, Abstract, Attachment], :project_id => project.id can :update, Text, :project_id => project.id, :user_level => current_role_name can :manage, [Asset], :project_id => project.id, :user_level => current_role_name end def auteur_scenior can :manage, [Project, Introduction, Abstract, Text, Conclusion, Asset, Attachment], :project_id => project.id end end 
+1
source

The authorize_resource method calls authorize! in the class if no instance is passed to it. Without using load_resource or load_and_authorize_resource you pass nil to authorize_resource before_filter.

Example from CanCan documentation :

 #authorize_resource(*args) ⇒ Object authorize!(params[:action].to_sym, @article || Article) 

If you want to load records from the database with your own method (instead of CanCan load_resource ) and have more controls, then you can create your own method, for example load_thing , and call it with prepend_before_filter :load_thing . This will load the entry into the instance variable before calling authorize_resource , ensuring that the instance variable is not nil, and the rules specified in the capability file are checked.

0
source

All Articles