如何检查 if_attribute :id => is_in { 递归方法中的 ids 数组 }

发布于 2025-01-07 01:16:49 字数 1371 浏览 0 评论 0原文

我有一个资源数据库,其中资源可以属于不同的位置。用户和组(自引用用户表)可以在不同位置具有不同的角色。组可以位于其他组内。授权对于使用“if_attribute”检查 location_id 是否在允许用户显示、编辑等的 location_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

由于组可以彼此“嵌套”,我认为我'必须使用递归方法来查找所有“合法”位置 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

使用在“授权执行”例程之外定义的方法:

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 (undefined method `find_group_location_ids' for (Authorization::Engine::AttributeValidator:0x7fb63448e2b0)

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

我如何使用 if_attribute通过递归方法查看 id 是否位于数组内?

I have a resource database where resources can belong to different locations. Users and groups (self-referential user table) can have different roles on different locations. Groups can be inside other groups. Authorization works well for single users using 'if_attribute' to check if the location_id is among the location_ids that the user is allowed to show, edit, etc.:

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

Since the groups can be "nested" inside each other, I have figured that I'll have to use a recursive method to find all the "legal" location ids. I tried this:

 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

with the method defined outside the 'authorization do'-routine:

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

The problem is that the method call doesn't find the method. I get this error:

NoMethodError (undefined method `find_group_location_ids' for (Authorization::Engine::AttributeValidator:0x7fb63448e2b0)

I have tried to place the method definition on a lot of different places, but with no luck.

How can I use if_attribute to see if an id is inside an array from a recursive method?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

仄言 2025-01-14 01:16:49

我从 google groups 的 declarative_authorization 小组的 steffenb 那里得到了一些帮助(他是 declarative_authorization 的作者)。解决方案是将方法移至用户模型:

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

I got som help from steffenb at the declarative_authorization group at google groups (he is the author of declarative_authorization). The solution was to move the method to the user model:

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

and to call it in this way from 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文