comment vérifier if_attribute: id=> is_in {tableau d'identifiants de la méthode récursive}
-
28-10-2019 - |
Question
J'ai une base de données de ressources où les ressources peuvent appartenir à différents emplacements. Les utilisateurs et les groupes (table des utilisateurs autoréférentiels) peuvent avoir des rôles différents à différents emplacements. Les groupes peuvent être à l'intérieur d'autres groupes. L'autorisation fonctionne bien pour les utilisateurs uniques utilisant 'if_attribute' pour vérifier si le location_id fait partie des location_ids que l'utilisateur est autorisé à afficher, modifier, 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
Puisque les groupes peuvent être "imbriqués" les uns dans les autres, j'ai pensé que je devrais utiliser une méthode récursive pour trouver tous les identifiants de localisation "légaux". J'ai essayé ceci:
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
avec la méthode définie en dehors de la routine 'autorisation 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
Le problème est que l'appel de méthode ne trouve pas la méthode. J'obtiens cette erreur:
NoMethodError (méthode non définie `find_group_location_ids 'pour (Authorization :: Engine :: AttributeValidator: 0x7fb63448e2b0)
J'ai essayé de placer la définition de méthode à de nombreux endroits différents, mais sans succès.
Comment puis-je utiliser if_attribute pour voir si un identifiant se trouve dans un tableau à partir d'une méthode récursive?
La solution
J'ai obtenu de l'aide de steffenb au groupe declarative_authorization de google groups (il est l'auteur de declarative_authorization).La solution était de déplacer la méthode vers le modèle utilisateur:
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
et pour l'appeler de cette manière depuis 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