Module: ActiveRecord::Acts::MaterializedPath::InstanceMethods
- Defined in:
- lib/acts_as_materialized_path.rb
Instance Method Summary collapse
-
#ancestors(include_self = false) ⇒ Object
returns an array of parents to root.
-
#children ⇒ Object
returns an array of children (empty if this is a leaf).
-
#depth ⇒ Object
returns the depth of this node in the tree (0 based).
-
#descendants(include_self = false) ⇒ Object
TODO.
- #destroy ⇒ Object
- #handle_new_record_code ⇒ Object
- #is_leaf? ⇒ Boolean
- #left_most_child ⇒ Object
- #nextvalue(path) ⇒ Object
- #parent ⇒ Object
- #right_sibling ⇒ Object
- #save ⇒ Object
- #save! ⇒ Object
- #save_as_child_of(parent) ⇒ Object
- #save_as_relation(parent_or_sibling, sibling) ⇒ Object
- #save_as_sibling_of(sibling) ⇒ Object
- #set_path(path) ⇒ Object
- #siblings(include_self = false) ⇒ Object
- #the_path(truncate = false) ⇒ Object
Instance Method Details
#ancestors(include_self = false) ⇒ Object
returns an array of parents to root
336 337 338 339 340 341 342 |
# File 'lib/acts_as_materialized_path.rb', line 336 def ancestors(include_self = false) self.class.find(:all, :conditions => [ mp_between, the_path(!include_self) ], :order => mp_asc ) end |
#children ⇒ Object
returns an array of children (empty if this is a leaf)
323 324 325 |
# File 'lib/acts_as_materialized_path.rb', line 323 def children self.class.siblings(the_path) end |
#depth ⇒ Object
returns the depth of this node in the tree (0 based)
345 346 347 |
# File 'lib/acts_as_materialized_path.rb', line 345 def depth the_path.count(mp_delimiter)-1 end |
#descendants(include_self = false) ⇒ Object
TODO
350 351 352 353 354 355 356 |
# File 'lib/acts_as_materialized_path.rb', line 350 def descendants(include_self = false) self.class.find(:all, :conditions => [ mp_like, "#{the_path}%" ], :order => mp_asc ) end |
#destroy ⇒ Object
202 203 204 205 206 207 208 209 210 211 |
# File 'lib/acts_as_materialized_path.rb', line 202 def destroy raise DestroyNotLeaf unless children.length == 0 #or # self.class.transaction do # children.each do |child| # child.destroy # end # end super end |
#handle_new_record_code ⇒ Object
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 |
# File 'lib/acts_as_materialized_path.rb', line 263 def handle_new_record_code self.class.transaction do basepath = '' if mp_parent_id_for_save.to_i > 0 relation = mp_parent_id_for_save sibling = false elsif mp_sibling_id_for_save.to_i > 0 relation = mp_sibling_id_for_save sibling = true end basepath = self.class.find(relation).the_path(sibling) if relation nextval = nextvalue(basepath) set_path(basepath+self.class.num2path_string(nextval)+mp_delimiter) end end |
#is_leaf? ⇒ Boolean
186 187 188 |
# File 'lib/acts_as_materialized_path.rb', line 186 def is_leaf? !left_most_child end |
#left_most_child ⇒ Object
178 179 180 181 182 183 184 |
# File 'lib/acts_as_materialized_path.rb', line 178 def left_most_child self.class.find(:first, :conditions => ["#{mp_like}", the_path + '_' * mp_places + mp_delimiter], :order => mp_asc) end |
#nextvalue(path) ⇒ Object
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/acts_as_materialized_path.rb', line 219 def nextvalue(path) last = self.class.find(:first, :select => mp_column, :conditions => [mp_like, path + '_' * mp_places + mp_delimiter], :order => mp_desc, :lock => true) if last last_path = last.the_path if i = last_path.index(mp_regexp) leaf = last_path[i, mp_places] else leaf = last_path end nextval = leaf.to_i(mp_base).next else nextval = 0 end return nextval end |
#parent ⇒ Object
328 329 330 331 332 333 |
# File 'lib/acts_as_materialized_path.rb', line 328 def parent self.class.find(:first, :conditions => [ mp_eq, the_path(true) ]) end |
#right_sibling ⇒ Object
191 192 193 194 195 196 197 198 199 |
# File 'lib/acts_as_materialized_path.rb', line 191 def right_sibling self.class.find(:first, :conditions => ["#{mp_gt} and #{mp_lt} and length(#{mp_column}) = ?", the_path, the_path(true)+'~', the_path.length], :order => mp_asc) end |
#save ⇒ Object
245 246 247 248 249 250 251 252 |
# File 'lib/acts_as_materialized_path.rb', line 245 def save if new_record? && !the_path handle_new_record_code super else super end end |
#save! ⇒ Object
254 255 256 257 258 259 260 261 |
# File 'lib/acts_as_materialized_path.rb', line 254 def save! if new_record? && !the_path handle_new_record_code super else super end end |
#save_as_child_of(parent) ⇒ Object
299 300 301 |
# File 'lib/acts_as_materialized_path.rb', line 299 def save_as_child_of(parent) save_as_relation(parent, false) end |
#save_as_relation(parent_or_sibling, sibling) ⇒ Object
283 284 285 286 287 288 289 290 291 |
# File 'lib/acts_as_materialized_path.rb', line 283 def save_as_relation(parent_or_sibling, sibling) raise PathUpdateDisallowed unless new_record? && !the_path self.class.transaction do basepath = parent_or_sibling.the_path(sibling) nextval = nextvalue(basepath) set_path(basepath+self.class.num2path_string(nextval)+mp_delimiter) save end end |
#save_as_sibling_of(sibling) ⇒ Object
294 295 296 |
# File 'lib/acts_as_materialized_path.rb', line 294 def save_as_sibling_of(sibling) save_as_relation(sibling, true) end |
#set_path(path) ⇒ Object
214 215 216 |
# File 'lib/acts_as_materialized_path.rb', line 214 def set_path(path) write_attribute(mp_column.to_sym, path) end |
#siblings(include_self = false) ⇒ Object
316 317 318 319 320 |
# File 'lib/acts_as_materialized_path.rb', line 316 def siblings(include_self = false) res = self.class.siblings(the_path(true)) res.delete_if{|mp| mp.the_path == the_path} unless include_self return res end |
#the_path(truncate = false) ⇒ Object
304 305 306 307 308 309 310 311 312 313 |
# File 'lib/acts_as_materialized_path.rb', line 304 def the_path(truncate = false) materialized_path = self.send(mp_column) if truncate rex = Regexp.new('[[:alnum:]]{' + mp_places.to_s + '}' + '\\' + mp_delimiter) offset = materialized_path.rindex(rex) end materialized_path = materialized_path[0, offset] if offset return materialized_path end |