Domanda

Ho un database delle risorse in cui le risorse possono appartenere a posizioni diverse. Gli utenti e i gruppi (tabella utente autoreferenziale) possono avere ruoli diversi in luoghi diversi. I gruppi possono essere all'interno di altri gruppi. L'autorizzazione funziona bene per gli utenti singoli utilizzando "if_attribute" per verificare se la posizione_id è tra i location_ids che l'utente è autorizzato a mostrare, modificare, ecc.:

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

Poiché i gruppi possono essere "nidificati" l'uno dell'altro, ho pensato che dovrò usare un metodo ricorsivo per trovare tutti gli ID di posizione "legale". Ho provato questo:

 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

con il metodo definito al di fuori della "autorizzazione 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

Il problema è che la chiamata del metodo non trova il metodo. Ricevo questo errore:

NomeToDerror (Metodo non definito `Find_Group_Location_ids 'per (autorizzazione :: Engine :: Attributevalidator: 0x7FB63448E2B0)

Ho cercato di posizionare la definizione del metodo in molti posti diversi, ma senza fortuna.

Come posso usare if_attribute per vedere se un ID è all'interno di un array da un metodo ricorsivo?

È stato utile?

Soluzione

Ho ricevuto aiuto da STEFFENB presso il gruppo dichiarativo_authorization presso Google Groups (è autore di dichiarativo_authorizzazione). La soluzione era spostare il metodo al modello utente:

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

e chiamarlo in questo modo da 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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top