module IdPlease module ModelExtensions module ForGroup def children(*args) options = args.extract_options! roles = options[:roles] || [_auth_group_role] view = options[:view] || :subjects role_hash = {} subject_hash = {} assignments = if roles == :any _auth_assign_class.role_authorizable_eq(self).all(:include => [:subject, :role]) else _auth_assign_class.role_name_eq(*roles.collect(&:to_s)).role_authorizable_eq(self).all(:include => [:subject, :role]) end assignments.each do |a| name, subject = a.role.name.to_sym, a.subject role_hash.has_key?(name) ? role_hash[name] << subject : role_hash[name] = [subject] subject_hash.has_key?(subject) ? subject_hash[subject] << name : subject_hash[subject] = [name] if _auth_nested_groups == true && options[:nested] != false && subject._auth_is_group == true children = subject.children role_hash[name] |= children children.each { |child| subject_hash.has_key?(child) ? subject_hash[child] << name : subject_hash[child] = [name]} end end case view when :subjects subject_hash.keys when :subject_hash subject_hash when :roles role_hash.keys when :role_hash role_hash end end def has_role!(role_name, object = nil) if object && object.kind_of?(self.class) && role_name.to_s == _auth_group_role && self.children.include?(object) raise "Attempt to make circular membership loop" else super end end end end end