2013-08-28 5 views
7

私は現在、それぞれの条件に応じてCanCanの役割を分ける方法について固執しています。 私たちのアプリケーションでは、数学、英語、歴史など多くのカテゴリがあり、それぞれには多くのコースがあります。Rails:CanCanを使用して、単一のモデルのインスタンスに応じて複数のロールを定義できますか?

各ユーザーは、各カテゴリでさまざまな役割を持つことができます。たとえば、ジョンは数学の「読者」になることができます。つまり、数学に含まれるすべてのコースを読むことができます。ジョンは英語の "ライター"でもあり、英語ですべてのコースを読んだり、カテゴリ内のコースを作成したり、英語で作成したコースのみを編集/削除することができます。

これらがJohnが持つ唯一の役割であれば、彼はnavbarでカテゴリ履歴を見ることができず、歴史の中にあるコースへのアクセスが拒否されます。

これらは関係が設定されている方法です:私たちは

class Ability 
include CanCan::Ability 

def initialize(user) 
    user ||= User.new # guest user (not logged in) #guest 

    if user.has_role? :reader 
    reader(user) 
    end 

    if user.has_role? :writer 
    writer(user) 
    end 
end 

#BE ABLE TO SEE COURSES AND CATS FOR PERMITTED CATS. 
def reader(user) 
    can :read, Category, :roles => { :user_id => user.id, :level => "reader" } 
    ## how would we be able to limit reading of courses that are within permitted categories? something like category.courses ~~ 
end 

def writer(user) 
    reader(user) #inheriting from reader? this doesnt work because level is hardcoded into reader 
    can :read, Category, :roles => { :user_id => user.id, :level => "writer"} 
    # 1.you can read all courses in category that you are given permission to 
    # 2.you can write courses in permitted category 
    # 3.you can edit, delete courses that only youve created within permitted category 
end 
end 

質問持つability.rb/

class User < ActiveRecord::Base 
    has_many :roles 

    def has_role?(role_sym) 
    roles.any? { |r| r.level.underscore.to_sym == role_sym } 
    end 
end 

class Category < ActiveRecord::Base 
    has_many :roles 
    has_many :courses 
end 

class Role < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :category 
    attr_accessible :level, :category_id, :user_id 
end 

モデルで:

  1. はどのようにしての役割を分離します"リーダー"と "ライター"は正しい方法で?アクセスしているカテゴリ内のコースにはどのようにアクセスすればよいですか?

  2. ability.rbでリーダーメソッドとライターメソッドを定義した後、ビューページでどのように使用しますか?現在のドキュメントでは「<%if:?read、@ category%> 」のようなものが使われていますが、これは分離して定義したメソッドを使用していないようです。

p.s.ゲスト、リーダー、作家、編集者、マネージャー、管理者、app_admin(開発者)の7つの役割があります

私は3日間これを解決しようとしています。初心者!事前に感謝します

答えて

-2

あなたのgemfileに含めてください。

  1. 宝石 "カンカン"

  2. バンドルをインストールします。

  3. は、Gカンカンレール:能力

これはあなたのモデルで能力クラスを生成します。

以下のようにあなたの能力を定義してください。

しかし、あなたはすでにあなたがUserモデル、すなわち管理者やサポート定義された2つの役割を持つ

を持っているとしての役割、

が定義されていることを覚えておいてください。

class Ability 
     include CanCan::Ability 
     def initialize(user) 
     user||= User.new 
      can :read, :all 
     if user.role == 'admin' 
      can :manage, :all 
     else 
      can :read, :all 
      end 
     end 
    end 

4.ユーザーを制限したいリソース、 はそのコントローラで次のフィルタを使用します。

   load_and_authorize_resource 

5.ビューに表示されないように制限する場合。

<% if can? :manage, @flower %> 
    <td><%= link_to 'Edit', edit_flower_path(flower) %></td> 
    <% end %> 
    <% if can? :manage, @flower %> 
     <td><%= link_to 'Destroy', flower_path(flower), method: :delete, data: { confirm: 'Are you sure?' } %></td> 
    <% end %> 
0

私は今日、同じニーズに走ったとCanCan Wikiにこれを行う方法を発見しました。 )

class User < ActiveRecord::Base 
    ROLES = %w[admin moderator author banned] 
end 

2aにあなたはActiveRecordのを使用している場合は、移行を作成し、実行します:あなたの役割名を持つUserクラスの下で定数を作成します

1):

シンプルこれらの簡単な手順に従ってください

rails generate migration add_roles_mask_to_users roles_mask:integer 
rake db:migrate 

2b)を使用している場合、ユーザーモデルにこれらのフィールドを追加しますMongoid:

field :roles_mask, type: Integer 

3)あなたは、Userモデルに次のコードを追加する必要があります次:ロールに:あなたはattr_accessible追加することを忘れないでください、強力なパラメータを指定せずに工夫を使用している場合

# in models/user.rb 
def roles=(roles) 
    self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.inject(0, :+) 
end 

def roles 
    ROLES.reject do |r| 
    ((roles_mask.to_i || 0) & 2**ROLES.index(r)).zero? 
    end 
end 

4)あなたのユーザーモデル。

class ApplicationController < ActionController::Base 
    before_filter :configure_permitted_parameters, if: :devise_controller? 

    protected 

    def configure_permitted_parameters 
    devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:email, :password, :password_confirmation, roles: [])} 
    end 
end 

:あなたはRailsの3アプリで宝石として、または内蔵されてレール4のようにいずれか、strong_parametersと工夫使用している場合は、コントローラで許可リストにロールを追加することを忘れていけません5)これらの役割を設定するためのビューのチェックボックスを生成するには以下のコードを追加します。

<% for role in User::ROLES %> 
    <%= check_box_tag "user[roles][#{role}]", role, @user.roles.include?(role), {:name => "user[roles][]"}%> 
    <%= label_tag "user_roles_#{role}", role.humanize %><br /> 
<% end %> 
<%= hidden_field_tag "user[roles][]", "" %> 

6)最後に、あなたは能力クラスで、ユーザーの役割を確認するために便利な方法を追加することができます。

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

# in models/ability.rb 
can :manage, :all if user.is? :admin 

それだけです。

こちらがお役に立てば幸いです。

関連する問題