2013-05-31 125 views
1

我正在使用RoR(一個社交留言板(互聯網論壇))的項目,每個用戶都可以創建多個Board並從其他用戶加入多個Board。Cancan授權論壇

我不想重新發明輪子,所以我使用Devise進行身份驗證,並使用CanCan進行授權。但是我在實施,因爲下面的康康舞一些問題:

class Board < ActiveRecord::Base 
    has_many :memberships 
    has_many :users , :through => :memberships 
end 

class User < ActiveRecord::Base 
    has_many :memberships 
    has_many :boards, :through => :memberships 
end 

class Membership < ActiveRecord::Base 
    ROLE = ['Administrator', 'Moderator','Member', 'Banned'] 
    belongs_to :user 
    belongs_to :board 
end 

角色並不屬於用戶自己,它屬於用戶和董事會之間的關係,那就是會員。因此,我不知道誰是current_user,我也需要知道顯示的是哪個電路板,所以我認爲我必須將Membership而不是用戶發送給Ability類初始化程序?任何指導將不勝感激。

回答

2

你在正確的道路上。

如果您還沒有,請將其設置爲全新的能力。例如BoardAbility。我發現有用的是不要害怕傳入額外的依賴關係,並讓CanCan儘可能多地執行合理的評估。

class BoardAbility 
    include CanCan::Ability 

    attr_reader :requested_by, :requested_resource 

    def initialize requested_by, requested_resource 
    return nil unless (requested_by.is_a?(User) && requested_resource.is_a?(Board)) 

    @requested_by  = requested_by 
    @requested_resource = requested_resource 

    default_rules 
    end 

    private 

    def default_rules 
    # common abilities to all users 
    can :flag_offensive, :all 
    can :view_thread_count, :all 

    # find this user's role to this board to define more abilities 
    role = Membership.where(user_id: requested_by.id, board_id: requested_resource.id).pluck(:role).first 

    if ['Administrator', 'Moderator'].include? role 
     can :ban_users, Board, {id: requested_resource.id} 
    end 
    end 
end 

然後在你的BoardController中定義一個私有方法來表示我們沒有使用默認的CanCan Ability類。

def current_ability 
    @current_ability ||= BoardAbility.new(current_user, @board) 
end 

然後,當您在BoardController中時,使用通常的CanCan DSL。

authorize! :ban_user, @board 
+1

你真棒,謝謝! –