Module: PathTree
- Includes:
- Patterns
- Defined in:
- lib/path_tree.rb,
lib/ruby_19_patterns.rb,
lib/path_tree/version.rb
Overview
This module implements a tree structure by using a convention of converting a name into a path. Paths created by normalizing a name attribute and then separating levels with periods with the lowest level coming last.
In order to use this module, the model must respond to the first and all methods like ActiveRecord, have support for after_destroy and after_save callbacks, validates_* macros and include attributes for name, node_path, path, and parent_path.
Defined Under Namespace
Modules: ClassMethods, Patterns
Constant Summary collapse
- VERSION =
'1.0.12'.freeze
Constants included from Patterns
Patterns::LOWER_AE_PATTERN, Patterns::LOWER_A_PATTERN, Patterns::LOWER_C_PATTERN, Patterns::LOWER_E_PATTERN, Patterns::LOWER_I_PATTERN, Patterns::LOWER_N_PATTERN, Patterns::LOWER_O_PATTERN, Patterns::LOWER_U_PATTERN, Patterns::LOWER_Y_PATTERN, Patterns::SS_PATTERN, Patterns::UPPER_AE_PATTERN, Patterns::UPPER_A_PATTERN, Patterns::UPPER_C_PATTERN, Patterns::UPPER_D_PATTERN, Patterns::UPPER_E_PATTERN, Patterns::UPPER_I_PATTERN, Patterns::UPPER_N_PATTERN, Patterns::UPPER_O_PATTERN, Patterns::UPPER_U_PATTERN, Patterns::UPPER_Y_PATTERN
Class Method Summary collapse
Instance Method Summary collapse
-
#ancestors ⇒ Object
Get all ancestors of this node with the root node first.
-
#children ⇒ Object
Get all nodes that are direct children of this node.
-
#descendants ⇒ Object
Get all descendant of this node.
-
#expanded_paths ⇒ Object
Returns an array containing the paths of this node and those of all its ancestors.
-
#full_name(options = {}) ⇒ Object
Get the full name of a node including the names of all it’s parent nodes.
- #name=(value) ⇒ Object
- #node_path=(value) ⇒ Object
-
#parent ⇒ Object
Get the parent node.
-
#parent=(node) ⇒ Object
Set the parent node.
-
#parent_path=(value) ⇒ Object
Set the parent path.
- #path_delimiter ⇒ Object
-
#siblings ⇒ Object
Get all nodes that share the same parent as this node.
Class Method Details
.included(base) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/path_tree.rb', line 16 def self.included (base) base.extend(ClassMethods) base.validates_uniqueness_of :path base.validates_uniqueness_of :node_path, :scope => :parent_path base.validates_presence_of :name, :node_path, :path base.after_save do |record| if record.path_changed? and !record.path_was.nil? record.children.each do |child| child.update_attributes(:parent_path => record.path) end end record.instance_variable_set(:@children, nil) end base.after_destroy do |record| record.children.each do |child| child.update_attributes(:parent_path => record.parent_path) end end end |
Instance Method Details
#ancestors ⇒ Object
Get all ancestors of this node with the root node first.
219 220 221 222 223 224 225 226 227 |
# File 'lib/path_tree.rb', line 219 def ancestors ancestor_paths = ancestor_paths.pop if ancestor_paths.empty? [] else self.class.base_class.all(:conditions => {:path => ancestor_paths}).sort{|a,b| a.path.length <=> b.path.length} end end |
#children ⇒ Object
Get all nodes that are direct children of this node.
199 200 201 202 203 204 205 206 |
# File 'lib/path_tree.rb', line 199 def children unless @children childrens_path = new_record? ? path : path_was @children = self.class.base_class.all(:conditions => {:parent_path => childrens_path}) @children.each{|c| c.parent = self} end @children end |
#descendants ⇒ Object
Get all descendant of this node.
214 215 216 |
# File 'lib/path_tree.rb', line 214 def descendants self.class.base_class.path_like(path) end |
#expanded_paths ⇒ Object
Returns an array containing the paths of this node and those of all its ancestors.
230 231 232 |
# File 'lib/path_tree.rb', line 230 def self.class.(path) end |
#full_name(options = {}) ⇒ Object
Get the full name of a node including the names of all it’s parent nodes. Specify the separator string to use between values with :separator (defaults to “ > ”). You can also specify the context for the full name by specifying a path in :context. This will only render the names up to and not including that part of the tree.
143 144 145 146 147 148 149 |
# File 'lib/path_tree.rb', line 143 def full_name ( = {}) separator = [:separator] || " > " n = "" n << parent.full_name() if parent_path and parent_path != [:context] n << separator unless n.blank? n << name end |
#name=(value) ⇒ Object
184 185 186 187 188 189 190 |
# File 'lib/path_tree.rb', line 184 def name= (value) unless value == name self[:name] = value self.node_path = value if node_path.blank? end value end |
#node_path=(value) ⇒ Object
192 193 194 195 196 |
# File 'lib/path_tree.rb', line 192 def node_path= (value) pathified = self.class.pathify(value) self[:node_path] = pathified recalculate_path end |
#parent ⇒ Object
Get the parent node.
156 157 158 159 160 161 162 163 164 165 |
# File 'lib/path_tree.rb', line 156 def parent unless instance_variable_defined?(:@parent) if path.index(path_delimiter) @parent = self.class.base_class.first(:conditions => {:path => parent_path}) else @parent = nil end end @parent end |
#parent=(node) ⇒ Object
Set the parent node.
168 169 170 171 172 |
# File 'lib/path_tree.rb', line 168 def parent= (node) node_path = node.path if node self.parent_path = node_path unless parent_path == node_path @parent = node end |
#parent_path=(value) ⇒ Object
Set the parent path
175 176 177 178 179 180 181 182 |
# File 'lib/path_tree.rb', line 175 def parent_path= (value) unless value == parent_path self[:parent_path] = value recalculate_path remove_instance_variable(:@parent) if instance_variable_defined?(:@parent) end value end |
#path_delimiter ⇒ Object
151 152 153 |
# File 'lib/path_tree.rb', line 151 def path_delimiter self.class.path_delimiter end |
#siblings ⇒ Object
Get all nodes that share the same parent as this node.
209 210 211 |
# File 'lib/path_tree.rb', line 209 def siblings self.class.base_class.all(:conditions => {:parent_path => parent_path}).reject{|node| node == self} end |