2012-02-20 3 views
1

리소스가 다른 위치에 속할 수있는 리소스 데이터베이스가 있습니다. 사용자 및 그룹 (자체 참조 사용자 테이블)은 서로 다른 위치에서 서로 다른 역할을 수행 할 수 있습니다. 그룹은 다른 그룹 안에있을 수 있습니다. 권한은 그룹이 서로의 내부에 "중첩"될 수 있으므로 location_id는 사용자가 보여줄 수 있다는 location_ids, 편집 등 :if_attribute를 확인하는 방법 : id => is_in {재귀 적 메서드에서 ID 배열}

has_permission_on :locations do 
    to [:show, :new, :create, :edit, :update, :destroy] 
    if_attribute :id => is_in { (user.permissions.where(:role => "admin").collect {|i| Location.find_by_id(i.location_id).subtree_ids}.flatten.uniq)} 
end 

중 하나입니다 있는지 확인하는 'if_attribute'를 사용하여 단일 사용자를 위해 잘 작동합니다 , 나는 모든 "합법적 인"위치 식별자를 찾기 위해 재귀 적 방법을 사용해야한다는 것을 알았습니다. '인증 do' 루틴 외부에 정의 된 방법으로

has_permission_on :locations do 
    to [:show, :new, :create, :edit, :update, :destroy] 
    if_attribute :id => is_in { (user.permissions.where(:role => "admin").collect {|i| Location.find_by_id(i.location_id).subtree_ids} + find_group_location_ids(user)).flatten.uniq } 
end 

: 나는이 시도

def find_group_location_ids(user) 
    location_ids = [] 
    nested_group_location_ids(user) 
    def nested_group_location_ids(user) 
    user.group_memberships.each do |gm| 
     location_ids = location_ids + gm.user.location.id 
     nested_group_location_ids(gm.user) 
    end 
    end 
    return location_ids 
end 

문제는 메서드 호출 방법을 찾을 수 없다는 것입니다.

NoMethodError (정의되지 않은 메서드`find_group_location_ids '(인증 :: 엔진의 :: AttributeValidator : :이 오류가 0x7fb63448e2b0)

나는하지만 함께 다른 많은 장소에서의 메소드 정의를 배치하는 것을 시도했다 행운.

은 어떻게 ID가 재귀 적 방법에서 배열 안에 있는지 확인하기 위해 if_attribute를 사용할 수 있습니까?

답변

0

내가 구글 그룹에서 declarative_authorization 그룹 (그는 declarative_authorization의 저자)에 steffenb에서 솜 도움을 받았습니다 해결책은 메소드를 사용자 모델로 이동하는 것이 었습니다.

def find_group_location_ids 
    location_ids = [] 
    nested_group_location_ids(self) 
    def nested_group_location_ids(user) 
    user.group_memberships.each do |gm| 
     location_ids = location_ids + gm.user.location.id 
     nested_group_location_ids(gm.user) 
    end 
    end 
    return location_ids 
end 

및 autorization_rules.rb에서이 방법으로 그것을 전화 :

has_permission_on :locations do 
    to [:show, :new, :create, :edit, :update, :destroy] 
    if_attribute :id => is_in { (user.memberships.where(:role_id => "admin").collect {|i| Location.find_by_id(i.location_id).subtree_ids} + user.find_group_location_ids).flatten.uniq } 
end