Module: Mongoid::Tree::RationalNumbering
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/mongoid/tree/rational_numbering.rb
Overview
Mongoid::Tree::RationalNumbering
Provides rational number sorting on your tree structure. This makes it simple to query for a tree given a node in a single query. Given this tree Node 1
Node 1-1
Node 1-2
Node 1-2-1
Node 1-2-2
Node 1-2-2-1
Node 1-2-2-2
Node 1-2-3
Node 1-3
Node 2
Node 2-1
Node 2-1-1
Node 2-1-2
Node 2-2
Node 3 Node 4
The entire tree can be queried like this: node_2 = Node.where(title: “Node 2”).first node_1.tree returns:
- “Node 2”, “Node 2-1”, “Node 2-1-1”, “Node 2-1-2”, “Node 2-2”
-
Mongoid::Tree doesn’t use rational numbers by default. To enable rational numbering of children include both Mongoid::Tree and Mongoid::Tree::RationalNumbering into your document.
Utility methods
Defined Under Namespace
Modules: ClassMethods
Constant Summary collapse
- @@_disable_timestamp_count =
0
Instance Method Summary collapse
-
#ancestors ⇒ Mongoid::Criteria
Returns a chainable criteria for this document’s ancestors.
-
#at_bottom? ⇒ Boolean
Is this the lowest sibling?.
-
#at_top? ⇒ Boolean
Is this the highest sibling?.
-
#correct_rational_parent?(nv, dv) ⇒ Boolean
Verifies parent keys from calculation and query.
-
#disable_timestamp_callback ⇒ void
Disable the timestamps for the document type, and increase the disable count Will only disable once, even if called multiple times.
-
#enable_timestamp_callback ⇒ void
Enable the timestamps for the document type, and decrease the disable count Will only enable once, even if called multiple times.
-
#first_sibling_in_list ⇒ Mongoid::Document
Returns the highest sibling (could be self).
-
#forced_rational_number? ⇒ Boolean
Was the changed forced?.
-
#from_rational_number(rational_number) ⇒ void
Convert from rational number and set keys accordingly.
-
#higher_siblings ⇒ Mongoid::Criteria
Returns siblings above the current document.
-
#initialize(*args) ⇒ void
Initialize the rational tree document.
-
#last_sibling_in_list ⇒ Mongoid::Document
Returns the lowest sibling (could be self).
-
#lower_siblings ⇒ Mongoid::Criteria
Returns siblings below the current document.
-
#move_above(other) ⇒ void
Move this node above the specified node.
-
#move_below(other) ⇒ void
Move this node below the specified node.
-
#move_conflicting_nodes(nv, dv) ⇒ void
Move conflicting nodes for a given value.
-
#move_down ⇒ void
Move this node one position down.
-
#move_node_and_save_if_changed(node, new_rational_number) ⇒ void
Move a node to given rational number and save/update the node.
-
#move_to_bottom ⇒ void
Move this node below all its siblings.
-
#move_to_position(_position, opts = {}) ⇒ void
- INTERNAL
-
Move the document to a given position (integer based, starting with 1).
-
#move_to_rational_number(nv, dv, opts = {}) ⇒ void
- INTERNAL
-
Move the document to a given rational_number position.
-
#move_to_top ⇒ void
Move this node above all its siblings.
-
#move_up ⇒ void
Move this node one position up.
-
#moving_nodes? ⇒ Boolean
Currently moving nodes around?.
-
#parent_exists?(nv, dv) ⇒ Boolean
Check if a parent exists for the given nv/dv values.
-
#parent_rational_number ⇒ Object
Get the parent rational number or “root” rational number if no parent.
-
#position ⇒ Object
Returns the positional value for the current node.
-
#query_ancestor_rational_number ⇒ RationalNumber
Query the ancestor rational number.
-
#rational_number ⇒ RationalNumber
Convert to rational number.
-
#rekey_children ⇒ void
Rekey each of the children (usually forcefully if a tree has gone “crazy”).
-
#rekey_children? ⇒ Boolean
Check if children needs to be rekeyed.
-
#rekey_former_siblings ⇒ void
Rekey former siblings after a move.
-
#rekey_former_siblings? ⇒ Boolean
Should the former siblings be rekeyed?.
-
#save_with_force_rational_numbers! ⇒ Object
save when forcing rational numbers.
-
#set_initial_rational_number? ⇒ Boolean
Should the initial rational number value.
-
#set_rational_number(nv, dv, do_save = true) ⇒ Boolean
This can be used to set a rational number directly The node will be moved to the correct parent.
-
#shift_lower_nodes_from_other(other, direction) ⇒ void
Shift nodes between self and other (or including other) in one or the other direction.
-
#shift_nodes(nodes_to_shift, direction) ⇒ void
Shift nodes in a direction.
-
#shift_nodes_position(other, direction, exclude_other = false) ⇒ void
Shift nodes between self and other (or including other) in one or the other direction.
-
#siblings_between(other) ⇒ Mongoid::Criteria
Returns siblings between the current document and the other document Siblings with a position between this document’s position and the other document’s position.
-
#siblings_between_including_other(other) ⇒ Mongoid::Criteria
Return the siblings between this and other + other.
-
#tree ⇒ Object
Get the tree under the given node.
-
#tree_and_self ⇒ Object
Get the tree under the given node.
-
#update_rational_number ⇒ void
Update the rational numbers on the document if changes to parent or rational number has been changed.
-
#update_rational_number? ⇒ Boolean
Check if the rational number should be updated.
-
#validate_rational_hierarchy ⇒ Object
Validate that this document has the correct parent document through a query If not, the parent must be set before setting nv/dv driectly.
-
#without_timestamping(&block) ⇒ void
Call block without triggeringtimestamps.
Instance Method Details
#ancestors ⇒ Mongoid::Criteria
Returns a chainable criteria for this document’s ancestors
453 454 455 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 453 def ancestors base_class.unscoped { super } end |
#at_bottom? ⇒ Boolean
Is this the lowest sibling?
543 544 545 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 543 def at_bottom? lower_siblings.empty? end |
#at_top? ⇒ Boolean
Is this the highest sibling?
534 535 536 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 534 def at_top? higher_siblings.empty? end |
#correct_rational_parent?(nv, dv) ⇒ Boolean
Verifies parent keys from calculation and query
347 348 349 350 351 352 353 354 355 356 357 358 359 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 347 def correct_rational_parent?(nv, dv) q_rational_number = query_ancestor_rational_number # puts " #{self.name} correct_rational_parent? nv: #{nv} dv: #{dv} query_ancestor_rational_number: #{q_rational_number.inspect}" if q_rational_number.nil? if RationalNumber.new(nv,dv).parent.root? return true else return false end end return true if self.rational_number.parent == q_rational_number false end |
#disable_timestamp_callback ⇒ void
This method returns an undefined value.
Disable the timestamps for the document type, and increase the disable count Will only disable once, even if called multiple times
716 717 718 719 720 721 722 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 716 def # # puts "Disabling timestamp callback count: #{@@_disable_timestamp_count}" if self.respond_to?("updated_at") self.class.skip_callback(:update, :before, :set_updated_at ) if @@_disable_timestamp_count == 0 @@_disable_timestamp_count += 1 end end |
#enable_timestamp_callback ⇒ void
This method returns an undefined value.
Enable the timestamps for the document type, and decrease the disable count Will only enable once, even if called multiple times
729 730 731 732 733 734 735 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 729 def # # puts "Enabling timestamp callback count: #{@@_disable_timestamp_count}" if self.respond_to?("updated_at") @@_disable_timestamp_count -= 1 self.class.set_callback(:update, :before, :set_updated_at ) if @@_disable_timestamp_count == 0 end end |
#first_sibling_in_list ⇒ Mongoid::Document
Returns the highest sibling (could be self)
525 526 527 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 525 def first_sibling_in_list siblings_and_self.first end |
#forced_rational_number? ⇒ Boolean
Was the changed forced?
801 802 803 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 801 def forced_rational_number? !!@_forced_rational_number end |
#from_rational_number(rational_number) ⇒ void
This method returns an undefined value.
Convert from rational number and set keys accordingly
440 441 442 443 444 445 446 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 440 def from_rational_number(rational_number) self.rational_number_nv = rational_number.nv self.rational_number_dv = rational_number.dv self.rational_number_snv = rational_number.snv self.rational_number_sdv = rational_number.sdv self.rational_number_value = rational_number.number end |
#higher_siblings ⇒ Mongoid::Criteria
Returns siblings above the current document. Siblings with a position lower than this document’s position.
482 483 484 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 482 def higher_siblings self.siblings.where(:rational_number_value.lt => self.rational_number_value) end |
#initialize(*args) ⇒ void
Initialize the rational tree document
140 141 142 143 144 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 140 def initialize(*args) @_forced_rational_number = false @_rational_moving_nodes = false super end |
#last_sibling_in_list ⇒ Mongoid::Document
Returns the lowest sibling (could be self)
516 517 518 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 516 def last_sibling_in_list siblings_and_self.last end |
#lower_siblings ⇒ Mongoid::Criteria
Returns siblings below the current document. Siblings with a position greater than this document’s position.
472 473 474 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 472 def lower_siblings self.siblings.where(:rational_number_value.gt => self.rational_number_value) end |
#move_above(other) ⇒ void
This method returns an undefined value.
Move this node above the specified node
This method changes the node’s parent if nescessary.
656 657 658 659 660 661 662 663 664 665 666 667 668 669 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 656 def move_above(other) ensure_to_be_sibling_of(other) return if other.position == self.position + 1 @_rational_moving_nodes = true # If there are nodes between this and other before move, make sure they are shifted upwards before moving _direction = (self.position > other.position ? 1 : -1) _position = (_direction < 0 ? other.position + _direction : other.position) shift_nodes_position(other, _direction, (_direction > 0 ? false : true)) # There should not be conflicting nodes at this stage. move_to_position(_position) save! @_rational_moving_nodes = false end |
#move_below(other) ⇒ void
This method returns an undefined value.
Move this node below the specified node
This method changes the node’s parent if nescessary.
680 681 682 683 684 685 686 687 688 689 690 691 692 693 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 680 def move_below(other) ensure_to_be_sibling_of(other) return if other.position + 1 == self.position @_rational_moving_nodes = true _direction = (self.position > other.position ? 1 : -1) _position = (_direction > 0 ? other.position + _direction : other.position) shift_nodes_position(other, _direction, (_direction > 0 ? true : false)) move_to_position(_position) save! @_rational_moving_nodes = false end |
#move_conflicting_nodes(nv, dv) ⇒ void
This method returns an undefined value.
Move conflicting nodes for a given value
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 308 def move_conflicting_nodes(nv,dv) # As we are moving to the position of the conflicting sibling, it all items can be shifted similar to "move_above" conflicting_sibling = base_class.where(:rational_number_nv => nv).where(:rational_number_dv => dv).excludes(:id => self.id).first if (conflicting_sibling != nil) # puts "moving conflicting nodes" do # ensure_to_be_sibling_of(conflicting_sibling) return if conflicting_sibling.position == self.position + 1 # If there are nodes between this and conflicting_sibling before move, make sure their position shifted before moving _direction = (self.position > conflicting_sibling.position ? 1 : -1) _position = (_direction < 0 ? conflicting_sibling.position + _direction : conflicting_sibling.position) shift_nodes_position(conflicting_sibling, _direction, (_direction > 0 ? false : true)) end end end |
#move_down ⇒ void
This method returns an undefined value.
Move this node one position down
584 585 586 587 588 589 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 584 def move_down unless at_bottom? next_sibling = lower_siblings.first switch_with_sibling(next_sibling) unless next_sibling.nil? end end |
#move_node_and_save_if_changed(node, new_rational_number) ⇒ void
This method returns an undefined value.
Move a node to given rational number and save/update the node
416 417 418 419 420 421 422 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 416 def move_node_and_save_if_changed(node, new_rational_number) if new_rational_number != node.rational_number node.move_to_rational_number(new_rational_number.nv, new_rational_number.dv, {:force => true}) node.save_with_force_rational_numbers! # node.reload # Should caller be responsible for reloading? end end |
#move_to_bottom ⇒ void
This method returns an undefined value.
Move this node below all its siblings
562 563 564 565 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 562 def move_to_bottom return true if at_bottom? move_below(last_sibling_in_list) end |
#move_to_position(_position, opts = {}) ⇒ void
This method returns an undefined value.
- INTERNAL
-
Move the document to a given position (integer based, starting with 1)
if a document exists on the new position, all siblings are shifted right before moving this document can move without updating conflicting siblings by using :force in options
174 175 176 177 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 174 def move_to_position(_position, opts = {}) new_rational_number = parent_rational_number.child_from_position(_position) move_to_rational_number(new_rational_number.nv, new_rational_number.dv, opts) end |
#move_to_rational_number(nv, dv, opts = {}) ⇒ void
This method returns an undefined value.
- INTERNAL
-
Move the document to a given rational_number position
if a document exists on the new position, all siblings are shifted right before moving this document can move without updating conflicting siblings by using :ignore_conflicts in options
192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 192 def move_to_rational_number(nv, dv, opts = {}) # don't check for conflict if forced move move_conflicting_nodes(nv,dv) unless !!opts[:force] # shouldn't be any conflicting sibling now... self.from_rational_number(RationalNumber.new(nv,dv)) # if parent_id is unknown, find parent and set correct parent_id if self.parent_id.nil? and self.rational_number.root? # puts "!!!!!!!!! #{self.name} move_to_rational_number missing parent and NOT root rational number!" end end |
#move_to_top ⇒ void
This method returns an undefined value.
Move this node above all its siblings
552 553 554 555 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 552 def move_to_top return true if at_top? move_above(first_sibling_in_list) end |
#move_up ⇒ void
This method returns an undefined value.
Move this node one position up
572 573 574 575 576 577 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 572 def move_up unless at_top? prev_sibling = higher_siblings.last switch_with_sibling(prev_sibling) unless prev_sibling.nil? end end |
#moving_nodes? ⇒ Boolean
Currently moving nodes around?
808 809 810 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 808 def moving_nodes? !!@_rational_moving_nodes end |
#parent_exists?(nv, dv) ⇒ Boolean
Check if a parent exists for the given nv/dv values
Will return true if the parent is “root” and the node should be created as a root element
289 290 291 292 293 294 295 296 297 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 289 def parent_exists?(nv,dv) q_parent = base_class.where(:rational_number_nv => nv).where(:rational_number_dv => dv).excludes(:id => self.id).first if q_parent.nil? return true if RationalNumber.new(nv,dv).parent.root? else return true end false end |
#parent_rational_number ⇒ Object
Get the parent rational number or “root” rational number if no parent
773 774 775 776 777 778 779 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 773 def parent_rational_number if root? RationalNumber.new else self.parent.rational_number end end |
#position ⇒ Object
Returns the positional value for the current node
@return The positional value calculated from the rational number
462 463 464 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 462 def position self.rational_number.position end |
#query_ancestor_rational_number ⇒ RationalNumber
Query the ancestor rational number
331 332 333 334 335 336 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 331 def query_ancestor_rational_number # puts " #{self.name} query_ancestor_rational_number parent_id: #{self.parent_id}" check_parent = base_class.where(:_id => self.parent_id).first return nil if (check_parent.nil? || check_parent == []) check_parent.rational_number end |
#rational_number ⇒ RationalNumber
Convert to rational number
429 430 431 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 429 def rational_number RationalNumber.new(self.rational_number_nv, self.rational_number_dv, self.rational_number_snv, self.rational_number_sdv) end |
#rekey_children ⇒ void
This method returns an undefined value.
Rekey each of the children (usually forcefully if a tree has gone “crazy”)
374 375 376 377 378 379 380 381 382 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 374 def rekey_children _pos = 1 this_rational_number = self.rational_number self.children.each do |child| new_rational_number = this_rational_number.child_from_position(_pos) move_node_and_save_if_changed(child, new_rational_number) _pos += 1 end end |
#rekey_children? ⇒ Boolean
Check if children needs to be rekeyed
364 365 366 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 364 def rekey_children? persisted? && self.children? && ( self.previous_changes.include?("rational_number_nv") || self.previous_changes.include?("parent_ids") || self.changes.include?("rational_number_nv") || self.changes.include?("parent_ids") ) end |
#rekey_former_siblings ⇒ void
This method returns an undefined value.
Rekey former siblings after a move
400 401 402 403 404 405 406 407 408 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 400 def rekey_former_siblings former_siblings = base_class.where(:parent_id => attribute_was('parent_id')). and(:rational_number_value.gt => (attribute_was('rational_number_value') || 0)). excludes(:id => self.id) former_siblings.each do |prev_sibling| new_rational_number = prev_sibling.parent_rational_number.child_from_position(prev_sibling.position - 1) move_node_and_save_if_changed(prev_sibling, new_rational_number) end end |
#rekey_former_siblings? ⇒ Boolean
Should the former siblings be rekeyed?
390 391 392 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 390 def rekey_former_siblings? persisted? && self.previous_changes.include?("parent_id") end |
#save_with_force_rational_numbers! ⇒ Object
save when forcing rational numbers
815 816 817 818 819 820 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 815 def save_with_force_rational_numbers! # puts "-- Saving #{self.name} #{self.updated_at.utc}" if self.respond_to?("updated_at") @_forced_rational_number = true self.save! @_forced_rational_number = false end |
#set_initial_rational_number? ⇒ Boolean
Should the initial rational number value
794 795 796 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 794 def set_initial_rational_number? self.rational_number_value.nil? end |
#set_rational_number(nv, dv, do_save = true) ⇒ Boolean
This can be used to set a rational number directly The node will be moved to the correct parent
If the given nv/dv does not find an existing parent, it will add an validation error
If the given nv/dv is higher than the last sibling under the parent, the nv/dv will be recalculated to appropriate nv/dv values
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 220 def set_rational_number(nv,dv, do_save = true) # return true of already at the right spot # puts "#{self.name} - set_rational_number #{nv}/#{dv} self:#{self.rational_number_nv}/#{self.rational_number_dv}" return true if self.rational_number_nv == nv && self.rational_number_dv == dv && (!self.rational_number_nv_changed? && !self.rational_number_dv_changed?) # check if parent exist # puts " parent exists: #{parent_exists?(nv,dv).inspect}" unless parent_exists?(nv,dv) errors.add(:base, I18n.t(:parent_does_not_exist, :scope => [:mongoid, :errors, :messages, :tree, :rational], nv: nv, dv: dv) ) return false end # find other/conflicting sibling other = base_class.where(:rational_number_nv => nv).where(:rational_number_dv => dv).excludes(:id => self.id).first already_sibling_of = other.nil? ? false : self.sibling_of?(other) # puts " conflicting node: #{other.nil? ? '-' : other.name } already_sibling_of :#{already_sibling_of}" return false if ensure_to_have_correct_parent(nv,dv) == false move_to_rational = RationalNumber.new(nv,dv) unless other.nil? if already_sibling_of # puts " already sibling of other, so moving down" return if other.position == self.position + 1 # If there are nodes between this and other before move, make sure they are shifted upwards before moving _direction = (self.position > other.position ? 1 : -1) _position = (_direction < 0 ? other.position + _direction : other.position) shift_nodes_position(other, _direction, (_direction > 0 ? false : true)) # There should not be conflicting nodes at this stage. move_to_position(_position) else # puts " shifting lower nodes from other" shift_lower_nodes_from_other(other, 1) end else # make sure the new position is the next rational value under the parent # as there was no "other" to move new_parent = base_class.where(:id => self.parent_id).first if new_parent.nil? # count roots root_count = base_class.roots.count move_to_rational = RationalNumber.new.child_from_position(root_count+1) # puts " new parent is root root_count: #{root_count} new 'correct position' is : #{move_to_rational.nv}/#{move_to_rational.dv}" else child_count = new_parent.children.count move_to_rational = new_parent.rational_number.child_from_position(child_count+1) # puts " new parent is not root child_count: #{child_count} new 'correct position' is : #{move_to_rational.nv}/#{move_to_rational.dv}" end end move_to_rational_number(move_to_rational.nv, move_to_rational.dv, {:force => true}) if do_save save else true end end |
#shift_lower_nodes_from_other(other, direction) ⇒ void
This method returns an undefined value.
Shift nodes between self and other (or including other) in one or the other direction
620 621 622 623 624 625 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 620 def shift_lower_nodes_from_other(other, direction) # puts "#{self.name} shift_lower_nodes_from_other other: #{other.name} direction: #{direction} other.siblings_and_self.count: #{other.siblings_and_self.count}" range = [other.rational_number_value, other.siblings_and_self.last.rational_number_value].sort nodes_to_shift = other.siblings_and_self.where(:rational_number_value.gte => range.first, :rational_number_value.lte => range.last) shift_nodes(nodes_to_shift, direction) end |
#shift_nodes(nodes_to_shift, direction) ⇒ void
This method returns an undefined value.
Shift nodes in a direction
635 636 637 638 639 640 641 642 643 644 645 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 635 def shift_nodes(nodes_to_shift, direction) # puts "#{self.name} shift_nodes direction: #{direction}" do nodes_to_shift.each do |node_to_shift| pos = node_to_shift.position + direction # puts " shifting #{node_to_shift.name} from position #{node_to_shift.position} to #{pos}" node_to_shift.move_to_position(pos, {:force => true}) node_to_shift.save_with_force_rational_numbers! end end end |
#shift_nodes_position(other, direction, exclude_other = false) ⇒ void
This method returns an undefined value.
Shift nodes between self and other (or including other) in one or the other direction
600 601 602 603 604 605 606 607 608 609 610 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 600 def shift_nodes_position(other, direction, exclude_other = false) do # puts "#{self.name} shift_nodes_position other: #{other.name} direction #{direction} exclude_other: #{exclude_other}" if exclude_other nodes_to_shift = siblings_between(other) else nodes_to_shift = siblings_between_including_other(other) end shift_nodes(nodes_to_shift, direction) end end |
#siblings_between(other) ⇒ Mongoid::Criteria
Returns siblings between the current document and the other document Siblings with a position between this document’s position and the other document’s position.
494 495 496 497 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 494 def siblings_between(other) range = [self.rational_number_value, other.rational_number_value].sort self.siblings.where(:rational_number_value.gt => range.first, :rational_number_value.lt => range.last) end |
#siblings_between_including_other(other) ⇒ Mongoid::Criteria
Return the siblings between this and other + other
506 507 508 509 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 506 def siblings_between_including_other(other) range = [self.rational_number_value, other.rational_number_value].sort self.siblings.where(:rational_number_value.gte => range.first, :rational_number_value.lte => range.last) end |
#tree ⇒ Object
Get the tree under the given node
825 826 827 828 829 830 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 825 def tree low_rational_number = self.rational_number_value high_rational_number = self.rational_number.parent.child_from_position(self.position+1).number base_class.where(:rational_number_value.gt => low_rational_number, :rational_number_value.lt => high_rational_number) end |
#tree_and_self ⇒ Object
Get the tree under the given node
835 836 837 838 839 840 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 835 def tree_and_self low_rational_number = self.rational_number_value high_rational_number = self.rational_number.parent.child_from_position(self.position+1).number base_class.where(:rational_number_value.gte => low_rational_number, :rational_number_value.lt => high_rational_number) end |
#update_rational_number ⇒ void
This method returns an undefined value.
Update the rational numbers on the document if changes to parent or rational number has been changed
Should calculate next free nv/dv and set that if parent has changed. (set values to “missing and call missing function should work”)
If there are both changes to nv/dv and parent_id, nv/dv settings takes precedence over parent_id changes
751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 751 def update_rational_number if self.rational_number_nv_changed? && self.rational_number_dv_changed? && !self.rational_number_value.nil? && !set_initial_rational_number? self.set_rational_number(self.rational_number_nv, self.rational_number_dv, false) elsif self.parent_id_changed? || set_initial_rational_number? # only changed parent, needs to find next free position # Get rational number from new parent last_sibling = self.siblings.last if (last_sibling.nil?) new_rational_number = parent_rational_number.child_from_position(1) else new_rational_number = parent_rational_number.child_from_position(last_sibling.rational_number.position + 1) end self.move_to_rational_number(new_rational_number.nv, new_rational_number.dv) end end |
#update_rational_number? ⇒ Boolean
Check if the rational number should be updated
787 788 789 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 787 def update_rational_number? (set_initial_rational_number? || self.parent_id_changed? || (self.rational_number_nv_changed? && self.rational_number_dv_changed?)) && !self.forced_rational_number? && !self.moving_nodes? end |
#validate_rational_hierarchy ⇒ Object
Validate that this document has the correct parent document through a query If not, the parent must be set before setting nv/dv driectly
153 154 155 156 157 158 159 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 153 def validate_rational_hierarchy if self.rational_number_nv_changed? && self.rational_number_dv_changed? unless correct_rational_parent?(self.rational_number_nv, self.rational_number_dv) errors.add(:base, I18n.t(:cyclic, :scope => [:mongoid, :errors, :messages, :tree])) end end end |
#without_timestamping(&block) ⇒ void
This method returns an undefined value.
Call block without triggeringtimestamps
704 705 706 707 708 709 |
# File 'lib/mongoid/tree/rational_numbering.rb', line 704 def (&block) # # puts "without_timestamping: Automagic timpestamping enabled? #{self.class.auto_tree_timestamping}" () if self.class. yield () if self.class. end |