module Customize::Inherited

Public Class Methods

included(base) click to toggle source
# File lib/customize/inherited.rb, line 3
def self.included base
        base.extend ClassMethods

        base.has_one :inherit_node, :class_name=>Customize::InheritNode.name, :as=>:node, :dependent=>:destroy

        base.scope :ascents_for, lambda { |object, options={:include=>false}|
                ntn = Customize::InheritNode.table_name
                node = object.inherit_node
                condition_string = if options[:include]
                                                                                                 "#{ntn}.left <= ? and #{ntn}.right >= ?"
                                                                                         else
                                                                                                 "#{ntn}.left < ? and #{ntn}.right > ?"
                                                                                         end
                base.joins(:inherit_node).where(condition_string, node.left, node.right)
        }

        base.scope :descents_for, lambda { |object, options={:include=>false}|
                ntn = Customize::InheritNode.table_name
                node = object.inherit_node
                condition_string = if options[:include]
                                                                                                 "#{ntn}.left >= ? and #{ntn}.right <= ?"
                                                                                         else
                                                                                                 "#{ntn}.left > ? and #{ntn}.right < ?"
                                                                                         end
                base.joins(:inherit_node).where(condition_string, node.left, node.right)
        }

        base.after_create { |object|
                object.create_inherit_node
        }

        base.delegate :leaf?, :to=>:inherit_node

        base.before_destroy { |object|
                raise 'object should not have children when destroy' if object.inherit_node.children.size > 0
        }

        
        
end

Public Instance Methods

ascent_ids() click to toggle source
# File lib/customize/inherited.rb, line 106
def ascent_ids
        ascents.map(&:id)
end
ascents(options={:include=>false}) click to toggle source
# File lib/customize/inherited.rb, line 89
def ascents options={:include=>false}
        return [] if new_record?
        self.class.ascents_for self, options
end
children() click to toggle source
# File lib/customize/inherited.rb, line 69
def children
        inherit_node.children.collect(&:node)
end
descent_ids() click to toggle source
# File lib/customize/inherited.rb, line 110
def descent_ids
        descents.map(&:id)
end
descents() click to toggle source
# File lib/customize/inherited.rb, line 101
def descents
        return [] if new_record?
        self.class.descents_for self
end
inherit(parent) click to toggle source
# File lib/customize/inherited.rb, line 77
def inherit parent
        raise 'should be save first' if self.new_record?
        raise 'should be same class' if self.class != parent.class
        raise 'should not be self' if self.id == parent.id
        raise 'should not inherit descents' if self.descent_ids.include? parent.id
        raise 'should not inherit parent' if self.parent.try(:id) == parent.id
        self.class.transaction do
                inherit_node.destroy
                create_inherit_node(:parent_id=>parent.inherit_node.id)
        end
end
inherit_association(name, options={:include=>false}) click to toggle source
# File lib/customize/inherited.rb, line 94
def inherit_association name, options={:include=>false}
        a = association(name)
        sql = ascents(options).joins(name).select("#{a.aliased_table_name}.#{a.klass.primary_key}").to_sql
        a.klass.from("(#{sql}) as subquery, #{a.klass.table_name}").
                where("#{a.klass.table_name}.#{a.klass.primary_key} = subquery.#{a.klass.primary_key}")
end
label() click to toggle source
# File lib/customize/inherited.rb, line 73
def label
        self.to_s
end
parent() click to toggle source
# File lib/customize/inherited.rb, line 65
def parent
        inherit_node.parent_node.try(:node)
end