Module: Dagable::InstanceMethods
- Defined in:
- lib/dagable/instance_methods.rb
Overview
Instance methods mixed into every dagable model. Provides the public API for managing edges and traversing the DAG.
Instance Method Summary collapse
-
#add_child(child) ⇒ Object
Adds
childas a direct child of this node. -
#add_parent(parent) ⇒ Object
Adds
parentas a direct parent of this node. -
#predecessors ⇒ ActiveRecord::Relation
Returns all transitive ancestors (excluding self) as an
ActiveRecord::Relation. -
#remove_child(child) ⇒ Object
Removes
childas a direct child of this node. -
#remove_parent(parent) ⇒ Object
Removes
parentas a direct parent of this node. -
#self_and_predecessors ⇒ ActiveRecord::Relation
Returns this node and all its transitive ancestors as an
ActiveRecord::Relationvia a single ancestry table JOIN. -
#self_and_successors ⇒ ActiveRecord::Relation
Returns this node and all its transitive descendants as an
ActiveRecord::Relationvia a single ancestry table JOIN. -
#successors ⇒ ActiveRecord::Relation
Returns all transitive descendants (excluding self) as an
ActiveRecord::Relation.
Instance Method Details
#add_child(child) ⇒ Object
Adds child as a direct child of this node. Creates the edge record and updates the ancestry table with all implied transitive paths.
28 29 30 31 32 33 34 35 |
# File 'lib/dagable/instance_methods.rb', line 28 def add_child(child) ActiveRecord::Base.transaction do raise Errors::CyclicAssociation.new(self, child) if self_and_predecessors.exists?(id: child.id) edge = child_edges.find_or_create_by!(child_id: child.id) edge.link_ancestries end end |
#add_parent(parent) ⇒ Object
Adds parent as a direct parent of this node. Creates the edge record and updates the ancestry table with all implied transitive paths.
13 14 15 16 17 18 19 20 |
# File 'lib/dagable/instance_methods.rb', line 13 def add_parent(parent) ActiveRecord::Base.transaction do raise Errors::CyclicAssociation.new(parent, self) if self_and_successors.exists?(id: parent.id) edge = parent_edges.find_or_create_by!(parent_id: parent.id) edge.link_ancestries end end |
#predecessors ⇒ ActiveRecord::Relation
Returns all transitive ancestors (excluding self) as an ActiveRecord::Relation.
102 103 104 105 106 107 108 109 |
# File 'lib/dagable/instance_methods.rb', line 102 def predecessors ancestry_table = ancestry_class.table_name model_table = self.class.table_name self.class .joins("INNER JOIN #{ancestry_table} ON #{ancestry_table}.predecessor_id = #{model_table}.id") .where("#{ancestry_table}.successor_id = ? AND #{ancestry_table}.depth > 0", id) end |
#remove_child(child) ⇒ Object
Removes child as a direct child of this node. Destroys the edge record; the edge’s destroy callbacks repair ancestry incrementally, touching only the region reachable through the removed edge.
42 43 44 45 46 |
# File 'lib/dagable/instance_methods.rb', line 42 def remove_child(child) ActiveRecord::Base.transaction do child_edges.where(child_id: child.id).destroy_all end end |
#remove_parent(parent) ⇒ Object
Removes parent as a direct parent of this node. Destroys the edge record; the edge’s destroy callbacks repair ancestry incrementally, touching only the region reachable through the removed edge.
53 54 55 56 57 |
# File 'lib/dagable/instance_methods.rb', line 53 def remove_parent(parent) ActiveRecord::Base.transaction do parent_edges.where(parent_id: parent.id).destroy_all end end |
#self_and_predecessors ⇒ ActiveRecord::Relation
Returns this node and all its transitive ancestors as an ActiveRecord::Relation via a single ancestry table JOIN.
76 77 78 79 80 81 82 83 |
# File 'lib/dagable/instance_methods.rb', line 76 def self_and_predecessors ancestry_table = ancestry_class.table_name model_table = self.class.table_name self.class .joins("INNER JOIN #{ancestry_table} ON #{ancestry_table}.predecessor_id = #{model_table}.id") .where("#{ancestry_table}.successor_id = ?", id) end |
#self_and_successors ⇒ ActiveRecord::Relation
Returns this node and all its transitive descendants as an ActiveRecord::Relation via a single ancestry table JOIN.
63 64 65 66 67 68 69 70 |
# File 'lib/dagable/instance_methods.rb', line 63 def self_and_successors ancestry_table = ancestry_class.table_name model_table = self.class.table_name self.class .joins("INNER JOIN #{ancestry_table} ON #{ancestry_table}.successor_id = #{model_table}.id") .where("#{ancestry_table}.predecessor_id = ?", id) end |
#successors ⇒ ActiveRecord::Relation
Returns all transitive descendants (excluding self) as an ActiveRecord::Relation.
89 90 91 92 93 94 95 96 |
# File 'lib/dagable/instance_methods.rb', line 89 def successors ancestry_table = ancestry_class.table_name model_table = self.class.table_name self.class .joins("INNER JOIN #{ancestry_table} ON #{ancestry_table}.successor_id = #{model_table}.id") .where("#{ancestry_table}.predecessor_id = ? AND #{ancestry_table}.depth > 0", id) end |