module Ltree::Hierarchy

Constants

VERSION

Public Instance Methods

at_depth(depth) click to toggle source
# File lib/ltree_hierarchy/hierarchy.rb, line 39
def at_depth(depth)
  where(["NLEVEL(#{table_name}.#{ltree_path_column}) = ?", depth])
end
has_ltree_hierarchy(options = {}) click to toggle source
# File lib/ltree_hierarchy/hierarchy.rb, line 3
def has_ltree_hierarchy(options = {})
  options = {
    fragment: :id,
    parent_fragment: :parent_id,
    path: :path,
    optional: true
  }.merge(options)

  options.assert_valid_keys(:fragment, :parent_fragment, :path, :optional)

  cattr_accessor :ltree_fragment_column, :ltree_parent_fragment_column, :ltree_path_column

  self.ltree_fragment_column = options[:fragment]
  self.ltree_parent_fragment_column = options[:parent_fragment]
  self.ltree_path_column = options[:path]

  belongs_to_parent_opts = {
    class_name: name,
    foreign_key: ltree_parent_fragment_column,
    primary_key: ltree_fragment_column,
    optional: true
  }

  belongs_to :parent, belongs_to_parent_opts
  validate :prevent_circular_paths, if: :ltree_parent_fragment_changed?

  after_create :commit_path
  before_update :assign_path, :cascade_path_change, if: :ltree_parent_fragment_changed?

  include InstanceMethods
end
leaves() click to toggle source
# File lib/ltree_hierarchy/hierarchy.rb, line 43
def leaves
  subquery = where("#{table_name}.#{ltree_parent_fragment_column} IS NOT NULL")
    .select("DISTINCT #{table_name}.#{ltree_parent_fragment_column}")

  where("#{table_name}.#{ltree_fragment_column} NOT IN(#{subquery.to_sql})")
end
lowest_common_ancestor_paths(paths) click to toggle source
# File lib/ltree_hierarchy/hierarchy.rb, line 50
def lowest_common_ancestor_paths(paths)
  sql = if paths.respond_to?(:to_sql)
    "SELECT LCA(ARRAY(#{paths.to_sql}))"
  else
    return [] if paths.empty?
    safe_paths = paths.map { |p| "#{connection.quote(p)}::ltree" }
    "SELECT LCA(ARRAY[#{safe_paths.join(", ")}])"
  end
  connection.select_values(sql)
end
lowest_common_ancestors(paths) click to toggle source
# File lib/ltree_hierarchy/hierarchy.rb, line 61
def lowest_common_ancestors(paths)
  where("#{table_name}.#{ltree_path_column}" => lowest_common_ancestor_paths(paths))
end
roots() click to toggle source
# File lib/ltree_hierarchy/hierarchy.rb, line 35
def roots
  where("#{table_name}.#{ltree_parent_fragment_column}" => nil)
end