2013-05-31 2 views
1

저는 모든 사용자가 여러 보드를 만들고 다른 사용자의 여러 보드에 참여할 수있는 소셜 메시지 보드 (인터넷 포럼) 인 RoR을 사용하는 프로젝트를 진행하고 있습니다.Cancan Authorization Forum

저는 인증을 위해 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인지 알지 못합니다. 어떤 보드가 표시되는지 알아야하기 때문에, 사용자 대신 멤버십을 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

감사합니다. –