Skip to content

Instantly share code, notes, and snippets.

@voltechs
Created July 6, 2012 23:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save voltechs/3063410 to your computer and use it in GitHub Desktop.
Save voltechs/3063410 to your computer and use it in GitHub Desktop.
class Group < ActiveRecord::Base
set_primary_key :id
belongs_to :type, class_name: "GroupType"
belongs_to :parent, class_name: "Group", foreign_key: "parent_id"
has_many :children, class_name: "Group", foreign_key: "parent_id"
# Haven't played around with this part too much yet.
accepts_nested_attributes_for :children
# NOTE:
# 1. Shouldn't really need to include :user and check their activity
# (I think that might be able to be done in the Membership class, but
# it should also be handled via the membership. Maybe even strictly.
# 2. Should a user ever really be "deactivated"?
# 3. An expiration date of 0000-00-00 will never expire
has_many :memberships, :include => :user, :conditions => [ '(memberships.expiration = 0000-00-00 OR memberships.expiration > ?) AND users.active = 1', Date.today]
has_many :roles, :through => :memberships, :order => 'roles.rank'
has_many :members, :through => :memberships, :source => :user
has_many :ordered_members, :through => :members, :source => :user, :order => 'roles.rank'
# Provides a list of groups that are subordinate to none. (Mwahahaha)
scope :roots, :conditions => { :parent_id => "" }
# Checks to see whether or not this group has a parent.
# In other words, whether it is subordinate to another
# group or not.
#
# * *Returns* :
# - +bool+ -> if this group has a parent
#
def has_parent?
!(parent.nil? || parent == self)
end
def ordered_members
members.joins(:memberships => :roles).order("roles.rank")
end
# Returns list of ancestors, starting from parent until root.
#
# subchild1.ancestors # => [child1, root]
def ancestors
node, nodes = self, []
nodes << node = node.parent while node.has_parent?
nodes
end
# Returns list of ancestors, including self until root.
#
# child.lineage # => [self, root]
def lineage
[] << self << ancestors
end
# Returns the root node of the tree.
def root
node = self
node = node.parent while node.parent
node
end
# Useful for permissions
def child_of(adult)
return parent.id == adult.id || (parent.child_of(adult) if has_parent?) || false
end
# Returns the short name of the group
def short
read_attribute(:short).empty? ? id : read_attribute(:short)
end
def as_json(options={})
super(:include => [:children])
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment