Ruby on rails 3 如何检查_属性:id=>;是{递归方法的ID数组}中的

Ruby on rails 3 如何检查_属性:id=>;是{递归方法的ID数组}中的,ruby-on-rails-3,declarative-authorization,Ruby On Rails 3,Declarative Authorization,我有一个资源数据库,其中的资源可以属于不同的位置。用户和组(自引用用户表)可以在不同的位置上具有不同的角色。组可以位于其他组内。使用“if_属性”检查位置标识是否在允许用户显示、编辑等的位置标识中,授权对单个用户有效: has_permission_on :locations do to [:show, :new, :create, :edit, :update, :destroy] if_attribute :id => is_in { (user.permissions.wh

我有一个资源数据库,其中的资源可以属于不同的位置。用户和组(自引用用户表)可以在不同的位置上具有不同的角色。组可以位于其他组内。使用“if_属性”检查位置标识是否在允许用户显示、编辑等的位置标识中,授权对单个用户有效:

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
由于这些组可以相互“嵌套”在一起,因此我认为必须使用递归方法来查找所有“合法”位置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} + find_group_location_ids(user)).flatten.uniq }
end
使用在“授权do”例程之外定义的方法:

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(未定义的方法“查找组位置ID”(Authorization::Engine::AttributeValidator:0x7fb63448e2b0)

我曾尝试将方法定义放在许多不同的地方,但没有成功


如何使用if_属性查看递归方法中的数组中是否有id?

我在google groups的声明性_授权组(他是声明性_授权的作者)获得了steffenb的som帮助。解决方案是将该方法移动到用户模型:

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