Module: ActiveRecord::Acts::NestedSet::InstanceMethods
- Defined in:
- lib/active_record/acts/nested_set.rb
Instance Method Summary collapse
-
#add_child(child) ⇒ Object
Adds a child to this object in the tree.
-
#all_children ⇒ Object
Returns a set of all of its children and nested children.
-
#before_destroy ⇒ Object
Prunes a branch off of the tree, shifting all of the elements on the right back to the left so the counts still work.
-
#child? ⇒ Boolean
Returns true is this is a child node.
-
#children_count ⇒ Object
Returns the number of nested children of this object.
-
#direct_children ⇒ Object
Returns a set of only this entry’s immediate children.
-
#full_set ⇒ Object
Returns a set of itself and all of its nested children.
-
#root? ⇒ Boolean
Returns true is this is a root node.
-
#unknown? ⇒ Boolean
Returns true if we have no idea what this is.
Instance Method Details
#add_child(child) ⇒ Object
Adds a child to this object in the tree. If this object hasn’t been initialized, it gets set up as a root node. Otherwise, this method will update all of the other elements in the tree and shift them to the right, keeping everything balanced.
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/active_record/acts/nested_set.rb', line 140 def add_child( child ) self.reload child.reload if child.root? raise "Adding sub-tree isn\'t currently supported" else if ( (self[left_col_name] == nil) || (self[right_col_name] == nil) ) # Looks like we're now the root node! Woo self[left_col_name] = 1 self[right_col_name] = 4 # What do to do about validation? return nil unless self.save child[parent_column] = self.id child[left_col_name] = 2 child[right_col_name]= 3 return child.save else # OK, we need to add and shift everything else to the right child[parent_column] = self.id right_bound = self[right_col_name] child[left_col_name] = right_bound child[right_col_name] = right_bound + 1 self[right_col_name] += 2 self.class.base_class.transaction { self.class.base_class.update_all( "#{left_col_name} = (#{left_col_name} + 2)", "#{scope_condition} AND #{left_col_name} >= #{right_bound}" ) self.class.base_class.update_all( "#{right_col_name} = (#{right_col_name} + 2)", "#{scope_condition} AND #{right_col_name} >= #{right_bound}" ) self.save child.save } end end end |
#all_children ⇒ Object
Returns a set of all of its children and nested children
187 188 189 |
# File 'lib/active_record/acts/nested_set.rb', line 187 def all_children self.class.base_class.find(:all, :conditions => "#{scope_condition} AND (#{left_col_name} > #{self[left_col_name]}) and (#{right_col_name} < #{self[right_col_name]})" ) end |
#before_destroy ⇒ Object
Prunes a branch off of the tree, shifting all of the elements on the right back to the left so the counts still work.
198 199 200 201 202 203 204 205 206 207 |
# File 'lib/active_record/acts/nested_set.rb', line 198 def before_destroy return if self[right_col_name].nil? || self[left_col_name].nil? dif = self[right_col_name] - self[left_col_name] + 1 self.class.base_class.transaction { self.class.base_class.delete_all( "#{scope_condition} and #{left_col_name} > #{self[left_col_name]} and #{right_col_name} < #{self[right_col_name]}" ) self.class.base_class.update_all( "#{left_col_name} = (#{left_col_name} - #{dif})", "#{scope_condition} AND #{left_col_name} >= #{self[right_col_name]}" ) self.class.base_class.update_all( "#{right_col_name} = (#{right_col_name} - #{dif} )", "#{scope_condition} AND #{right_col_name} >= #{self[right_col_name]}" ) } end |
#child? ⇒ Boolean
Returns true is this is a child node
125 126 127 128 |
# File 'lib/active_record/acts/nested_set.rb', line 125 def child? parent_id = self[parent_column] !(parent_id == 0 || parent_id.nil?) && (self[left_col_name] > 1) && (self[right_col_name] > self[left_col_name]) end |
#children_count ⇒ Object
Returns the number of nested children of this object.
177 178 179 |
# File 'lib/active_record/acts/nested_set.rb', line 177 def children_count return (self[right_col_name] - self[left_col_name] - 1)/2 end |
#direct_children ⇒ Object
Returns a set of only this entry’s immediate children
192 193 194 |
# File 'lib/active_record/acts/nested_set.rb', line 192 def direct_children self.class.base_class.find(:all, :conditions => "#{scope_condition} and #{parent_column} = #{self.id}") end |
#full_set ⇒ Object
Returns a set of itself and all of its nested children
182 183 184 |
# File 'lib/active_record/acts/nested_set.rb', line 182 def full_set self.class.base_class.find(:all, :conditions => "#{scope_condition} AND (#{left_col_name} BETWEEN #{self[left_col_name]} and #{self[right_col_name]})" ) end |
#root? ⇒ Boolean
Returns true is this is a root node.
119 120 121 122 |
# File 'lib/active_record/acts/nested_set.rb', line 119 def root? parent_id = self[parent_column] (parent_id == 0 || parent_id.nil?) && (self[left_col_name] == 1) && (self[right_col_name] > self[left_col_name]) end |
#unknown? ⇒ Boolean
Returns true if we have no idea what this is
131 132 133 |
# File 'lib/active_record/acts/nested_set.rb', line 131 def unknown? !root? && !child? end |