Module: ActiveRecord::Acts::NestedSet::InstanceMethods
- Defined in:
- lib/active_record/acts/nested_set.rb
Instance Method Summary collapse
-
#add_child(child) ⇒ Object
Added a child to this object in the tree.
-
#all_children ⇒ Object
Returns a set of all of it’s 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 entries immediate children.
-
#full_set ⇒ Object
Returns a set of itself and all of it’s 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
Added 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 balanaced.
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 175 |
# File 'lib/active_record/acts/nested_set.rb', line 141 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.transaction { self.class.update_all( "#{left_col_name} = (#{left_col_name} + 2)", "#{scope_condition} AND #{left_col_name} >= #{right_bound}" ) self.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 it’s children and nested children
188 189 190 |
# File 'lib/active_record/acts/nested_set.rb', line 188 def all_children self.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.
199 200 201 202 203 204 205 206 207 208 |
# File 'lib/active_record/acts/nested_set.rb', line 199 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.transaction { self.class.delete_all( "#{scope_condition} and #{left_col_name} > #{self[left_col_name]} and #{right_col_name} < #{self[right_col_name]}" ) self.class.update_all( "#{left_col_name} = (#{left_col_name} - #{dif})", "#{scope_condition} AND #{left_col_name} >= #{self[right_col_name]}" ) self.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
126 127 128 129 |
# File 'lib/active_record/acts/nested_set.rb', line 126 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.
178 179 180 |
# File 'lib/active_record/acts/nested_set.rb', line 178 def children_count return (self[right_col_name] - self[left_col_name] - 1)/2 end |
#direct_children ⇒ Object
Returns a set of only this entries immediate children
193 194 195 |
# File 'lib/active_record/acts/nested_set.rb', line 193 def direct_children self.class.find(:all, :conditions => "#{scope_condition} and #{parent_column} = #{self.id}") end |
#full_set ⇒ Object
Returns a set of itself and all of it’s nested children
183 184 185 |
# File 'lib/active_record/acts/nested_set.rb', line 183 def full_set self.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.
120 121 122 123 |
# File 'lib/active_record/acts/nested_set.rb', line 120 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
132 133 134 |
# File 'lib/active_record/acts/nested_set.rb', line 132 def unknown? !root? && !child? end |