module ClosureTree::NumericDeterministicOrdering

Public Instance Methods

_ct_reorder_children(minimum_sort_order_value = nil) click to toggle source
# File lib/closure_tree/numeric_deterministic_ordering.rb, line 29
def _ct_reorder_children(minimum_sort_order_value = nil)
  _ct.reorder_with_parent_id(_ct_id, minimum_sort_order_value)
end
_ct_reorder_prior_siblings_if_parent_changed() click to toggle source
# File lib/closure_tree/numeric_deterministic_ordering.rb, line 12
def _ct_reorder_prior_siblings_if_parent_changed
  as_5_1 = ActiveSupport.version >= Gem::Version.new('5.1.0')
  change_method = as_5_1 ? :saved_change_to_attribute? : :attribute_changed?

  if public_send(change_method, _ct.parent_column_name) && !@was_new_record
    attribute_method = as_5_1 ? :attribute_before_last_save : :attribute_was

    was_parent_id = public_send(attribute_method, _ct.parent_column_name)
    _ct.reorder_with_parent_id(was_parent_id)
  end
end
_ct_reorder_siblings(minimum_sort_order_value = nil) click to toggle source
# File lib/closure_tree/numeric_deterministic_ordering.rb, line 24
def _ct_reorder_siblings(minimum_sort_order_value = nil)
  _ct.reorder_with_parent_id(_ct_parent_id, minimum_sort_order_value)
  reload unless destroyed?
end
add_sibling(sibling, add_after = true) click to toggle source
# File lib/closure_tree/numeric_deterministic_ordering.rb, line 118
def add_sibling(sibling, add_after = true)
  fail "can't add self as sibling" if self == sibling

  if _ct.dont_order_roots && parent.nil?
    raise ClosureTree::RootOrderingDisabledError.new("Root ordering is disabled on this model")
  end

  # Make sure self isn't dirty, because we're going to call reload:
  save

  _ct.with_advisory_lock do
    prior_sibling_parent = sibling.parent
    reorder_from_value = if prior_sibling_parent == self.parent
      [self.order_value, sibling.order_value].compact.min
    else
      self.order_value
    end

    sibling.order_value = self.order_value
    sibling.parent = self.parent
    sibling._ct_skip_sort_order_maintenance!
    sibling.save # may be a no-op

    _ct_reorder_siblings(reorder_from_value)

    # The sort order should be correct now except for self and sibling, which may need to flip:
    sibling_is_after = self.reload.order_value < sibling.reload.order_value
    if add_after != sibling_is_after
      # We need to flip the sort orders:
      self_ov, sib_ov = self.order_value, sibling.order_value
      update_order_value(sib_ov)
      sibling.update_order_value(self_ov)
    end

    if prior_sibling_parent != self.parent
      prior_sibling_parent.try(:_ct_reorder_children)
    end
    sibling
  end
end
append_child(child_node) click to toggle source
# File lib/closure_tree/numeric_deterministic_ordering.rb, line 94
def append_child(child_node)
  add_child(child_node)
end
append_sibling(sibling_node) click to toggle source
# File lib/closure_tree/numeric_deterministic_ordering.rb, line 110
def append_sibling(sibling_node)
  add_sibling(sibling_node, true)
end
prepend_child(child_node) click to toggle source
# File lib/closure_tree/numeric_deterministic_ordering.rb, line 98
def prepend_child(child_node)
  child_node.order_value = -1
  child_node.parent = self
  child_node._ct_skip_sort_order_maintenance!
  if child_node.save
    _ct_reorder_children
    child_node.reload
  else
    child_node
  end
end
prepend_sibling(sibling_node) click to toggle source
# File lib/closure_tree/numeric_deterministic_ordering.rb, line 114
def prepend_sibling(sibling_node)
  add_sibling(sibling_node, false)
end
self_and_descendants_preordered() click to toggle source
# File lib/closure_tree/numeric_deterministic_ordering.rb, line 33
    def self_and_descendants_preordered
      # TODO: raise NotImplementedError if sort_order is not numeric and not null?
      join_sql = <<-SQL
        JOIN #{_ct.quoted_hierarchy_table_name} anc_hier
          ON anc_hier.descendant_id = #{_ct.quoted_hierarchy_table_name}.descendant_id
        JOIN #{_ct.quoted_table_name} anc
          ON anc.#{_ct.quoted_id_column_name} = anc_hier.ancestor_id
        JOIN #{_ct.quoted_hierarchy_table_name} depths
          ON depths.ancestor_id = #{_ct.quote(self.id)} AND depths.descendant_id = anc.#{_ct.quoted_id_column_name}
      SQL

      self_and_descendants
        .joins(join_sql)
        .group("#{_ct.quoted_table_name}.#{_ct.quoted_id_column_name}")
        .reorder(self.class._ct_sum_order_by(self))
    end