lib/customize/inherited.rb in customize-0.0.5 vs lib/customize/inherited.rb in customize-0.0.6
- old
+ new
@@ -3,20 +3,44 @@
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 :left=>0, :right=>1
}
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
module ClassMethods
def root
joins(:inherit_node).where("parent_id is null")
@@ -48,32 +72,41 @@
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
- inherit_node.parent_id = parent.inherit_node.id
- right = parent.inherit_node.right
- InheritNode.where("right >= ?", inherit_node.left).update_all("right = right+2")
- inherit_node.left = right
- inherit_node.right = right + 1
- inherit_node.save
+ self.class.transaction do
+ inherit_node.parent_id = parent.inherit_node.id
+ right = parent.inherit_node.right
+ InheritNode.where("right >= ?", inherit_node.left).update_all("right = right+2")
+ inherit_node.left = right
+ inherit_node.right = right + 1
+ inherit_node.save
+ end
end
- def ascent_ids
- return [] if self.new_record?
- r = InheritNode.where("left < :left and right > :right and node_type = :type",:left=>inherit_node.left, :right=>inherit_node.right, :type=>self.class.name)
- r.pluck(:node_id)
+ def ascents options={:include=>false}
+ return [] if new_record?
+ self.class.ascents_for self, options
end
- def descent_ids
- return [] if self.new_record?
- r = InheritNode.where("left > :left and right < :right and node_type = :type",
- :left=>inherit_node.left, :right=>inherit_node.right, :type=>self.class.name)
- r.pluck(:node_id)
+ def inherit_association name, options={:include=>false}
+ association_table_name = association(name).aliased_table_name
+
+ r = ascents(options).joins(name).select("#{association_table_name}.*").uniq
+ r.map(&name).flatten
end
- def ascents
- self.class.find ascent_ids
+ def descents
+ return [] if new_record?
+ self.class.descents_for self
end
+ def ascent_ids
+ ascents.map(&:id)
+ end
+
+ def descent_ids
+ descents.map(&:id)
+ end
end
end