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.
[ show source ]
# File vendor/rails/activerecord/lib/active_record/acts/nested_set.rb, line 142
142: def add_child( child )
143: self.reload
144: child.reload
145:
146: if child.root?
147: raise "Adding sub-tree isn\'t currently supported"
148: else
149: if ( (self[left_col_name] == nil) || (self[right_col_name] == nil) )
150: # Looks like we're now the root node! Woo
151: self[left_col_name] = 1
152: self[right_col_name] = 4
153:
154: # What do to do about validation?
155: return nil unless self.save
156:
157: child[parent_column] = self.id
158: child[left_col_name] = 2
159: child[right_col_name]= 3
160: return child.save
161: else
162: # OK, we need to add and shift everything else to the right
163: child[parent_column] = self.id
164: right_bound = self[right_col_name]
165: child[left_col_name] = right_bound
166: child[right_col_name] = right_bound + 1
167: self[right_col_name] += 2
168: self.class.transaction {
169: self.class.update_all( "#{left_col_name} = (#{left_col_name} + 2)", "#{scope_condition} AND #{left_col_name} >= #{right_bound}" )
170: self.class.update_all( "#{right_col_name} = (#{right_col_name} + 2)", "#{scope_condition} AND #{right_col_name} >= #{right_bound}" )
171: self.save
172: child.save
173: }
174: end
175: end
176: end
Returns a set of all of its children and nested children
[ show source ]
# File vendor/rails/activerecord/lib/active_record/acts/nested_set.rb, line 189
189: def all_children
190: self.class.find(:all, :conditions => "#{scope_condition} AND (#{left_col_name} > #{self[left_col_name]}) and (#{right_col_name} < #{self[right_col_name]})" )
191: end
Prunes a branch off of the tree, shifting all of the elements on the right back to the left so the counts still work.
[ show source ]
# File vendor/rails/activerecord/lib/active_record/acts/nested_set.rb, line 200
200: def before_destroy
201: return if self[right_col_name].nil? || self[left_col_name].nil?
202: dif = self[right_col_name] - self[left_col_name] + 1
203:
204: self.class.transaction {
205: self.class.delete_all( "#{scope_condition} and #{left_col_name} > #{self[left_col_name]} and #{right_col_name} < #{self[right_col_name]}" )
206: self.class.update_all( "#{left_col_name} = (#{left_col_name} - #{dif})", "#{scope_condition} AND #{left_col_name} >= #{self[right_col_name]}" )
207: self.class.update_all( "#{right_col_name} = (#{right_col_name} - #{dif} )", "#{scope_condition} AND #{right_col_name} >= #{self[right_col_name]}" )
208: }
209: end
Returns true is this is a child node
[ show source ]
# File vendor/rails/activerecord/lib/active_record/acts/nested_set.rb, line 127
127: def child?
128: parent_id = self[parent_column]
129: !(parent_id == 0 || parent_id.nil?) && (self[left_col_name] > 1) && (self[right_col_name] > self[left_col_name])
130: end
Returns the number of nested children of this object.
[ show source ]
# File vendor/rails/activerecord/lib/active_record/acts/nested_set.rb, line 179
179: def children_count
180: return (self[right_col_name] - self[left_col_name] - 1)/2
181: end
Returns a set of only this entry’s immediate children
[ show source ]
# File vendor/rails/activerecord/lib/active_record/acts/nested_set.rb, line 194
194: def direct_children
195: self.class.find(:all, :conditions => "#{scope_condition} and #{parent_column} = #{self.id}")
196: end
Returns a set of itself and all of its nested children
[ show source ]
# File vendor/rails/activerecord/lib/active_record/acts/nested_set.rb, line 184
184: def full_set
185: self.class.find(:all, :conditions => "#{scope_condition} AND (#{left_col_name} BETWEEN #{self[left_col_name]} and #{self[right_col_name]})" )
186: end
Returns true is this is a root node.
[ show source ]
# File vendor/rails/activerecord/lib/active_record/acts/nested_set.rb, line 121
121: def root?
122: parent_id = self[parent_column]
123: (parent_id == 0 || parent_id.nil?) && (self[left_col_name] == 1) && (self[right_col_name] > self[left_col_name])
124: end
Returns true if we have no idea what this is
[ show source ]
# File vendor/rails/activerecord/lib/active_record/acts/nested_set.rb, line 133
133: def unknown?
134: !root? && !child?
135: end