как проверить if_attribute: id => is_in {массив идентификаторов из рекурсивного метода} - PullRequest
1 голос
/ 20 февраля 2012

У меня есть база данных ресурсов, где ресурсы могут принадлежать разным местам. Пользователи и группы (таблица со ссылками на себя) могут иметь разные роли в разных местах. Группы могут быть внутри других групп. Авторизация хорошо работает для отдельных пользователей, использующих if_attribute для проверки, находится ли location_id среди location_ids, которые пользователю разрешено отображать, редактировать и т. Д.:

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

Поскольку группы могут быть «вложенными» друг в друга, я решил, что мне придется использовать рекурсивный метод, чтобы найти все «допустимые» идентификаторы местоположения. Я попробовал это:

 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

с методом, определенным вне подпрограммы 'authorization 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 (неопределенный метод `find_group_location_ids 'для (Authorization :: Engine :: AttributeValidator: 0x7fb63448e2b0)

Я пытался разместить определение метода во многих местах, но безуспешно.

Как я могу использовать if_attribute, чтобы увидеть, находится ли id внутри массива из рекурсивного метода?

1 Ответ

0 голосов
/ 02 апреля 2012

Я получил некоторую помощь от steffenb в группе Declarative_authorization в группах Google (он является автором декларативного_авторизации). Решением было перенести метод в модель пользователя:

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
...