2012-02-22 4 views
0

私はCanCanをプロジェクトで使用して、各プロジェクトの各エンティティで異なる役割レベルを管理しています。 は、私はこれをやっている:Cancan条件

# 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 

それは私がユーザーROLE_NAMEを確認したときに動作しますが、私はこのような状態を使用したいとき後:

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

条件は影響しません。どうすればそれを動作させることができますか?

答えて

1

影響を及ぼす能力:私はload_and_authorize_resourceでauthorize_resourceを交換し、それはそれだ心配コントローラで

を。

1

私はuselyやっていることは次のとおりです。

1-私のUserクラスでの役割を定義し、ユーザーに影響を与えます。

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-で、私は私が最終的に解決策見つかった各役割の機能

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 
0

authorize_resourceメソッドは、インスタンスに渡されない限り、クラスのauthorize!を呼び出します。 load_resourceまたはload_and_authorize_resourceを使用しない場合、authorize_resource before_filterにはnilを渡します。

Example from the CanCan documentation

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

あなたが(代わりにカンカンのload_resourceの)独自の方法でデータベースからレコードをロードし、より多くの制御を持っているしたい場合は、あなたがload_thingのような独自のメソッドを作成し、それを呼び出すことができますprepend_before_filter :load_thingauthorize_resourceが呼び出される前にインスタンス変数にレコードをロードし、インスタンス変数がnilでなく、能力ファイルで指定されたルールがチェックされるようにします。