module PgLtree::Model

Public Instance Methods

ancestors() click to toggle source

Get ancestors

@return [ActiveRecord::Relation]

# File lib/pg_ltree/model.rb, line 158
def ancestors
  self_and_ancestors.where.not ltree_path_column => ltree_path
end
at_depth(depth) click to toggle source

Get nodes on the level

@param depth [Integer] Depth of the nodes @return [ActiveRecord::Relation] relations of nodes for the depth

# File lib/pg_ltree/model.rb, line 21
def at_depth(depth)
  where "NLEVEL(#{table_name}.#{ltree_path_column}) = ?", depth
end
cascade_destroy() click to toggle source

Delete all children for current path

@return [ActiveRecord::Relation]

# File lib/pg_ltree/model.rb, line 214
def cascade_destroy
  ltree_scope.where("#{self.class.table_name}.#{ltree_path_column} <@ ?", ltree_path_in_database).destroy_all
end
cascade_update() click to toggle source

Update all childen for current path

@return [ActiveRecord::Relation]

# File lib/pg_ltree/model.rb, line 204
def cascade_update
  ltree_scope
    .where("#{self.class.table_name}.#{ltree_path_column} <@ ?", ltree_path_before_last_save)
    .where("#{self.class.table_name}.#{ltree_path_column} != ?", ltree_path)
    .update_all("#{ltree_path_column} = ? || subpath(#{ltree_path_column}, nlevel(?))", ltree_path, ltree_path_before_last_save)
end
children() click to toggle source

Get children

@return [ActiveRecord::Relation]

# File lib/pg_ltree/model.rb, line 196
def children
  ltree_scope.where "? @> #{self.class.table_name}.#{ltree_path_column} AND nlevel(#{self.class.table_name}.#{ltree_path_column}) = NLEVEL(?) + 1",
    ltree_path, ltree_path
end
depth() click to toggle source

Get node depth

@return [Integer] node depth

# File lib/pg_ltree/model.rb, line 114
def depth
  ActiveRecord::Base.connection.select_all("SELECT NLEVEL('#{ltree_path}')").rows.flatten.first.to_i
end
descendants() click to toggle source

Get descendants

@return [ActiveRecord::Relation]

# File lib/pg_ltree/model.rb, line 172
def descendants
  self_and_descendants.where.not ltree_path_column => ltree_path
end
height() click to toggle source

Get node height

The height of a node is the number of edges on the longest downward path between that node and a leaf. The leaf nodes have height zero, and a tree with only a single node (hence both a root and leaf) has height zero. Conventionally, an empty tree (tree with no nodes, if such are allowed) has depth and height −1

@return [Number] height of the given node. Height of the tree for root node.

# File lib/pg_ltree/model.rb, line 107
def height
  self_and_descendants.maximum("NLEVEL(#{ltree_path_column})") - depth.to_i
end
leaf?() click to toggle source

Check what current node have leaves

@return [Boolean] True - if node have leaves, False - if node doesn’t have leaves

# File lib/pg_ltree/model.rb, line 144
def leaf?
  leaves.count == 0
end
leaves() click to toggle source

Get all leaves

@return [ActiveRecord::Relation] relations of node’s leaves

# File lib/pg_ltree/model.rb, line 28
def leaves
  subquery = unscoped.select("#{table_name}.#{ltree_path_column}")
    .from("#{table_name} AS subquery")
    .where("#{table_name}.#{ltree_path_column} <> subquery.#{ltree_path_column}")
    .where("#{table_name}.#{ltree_path_column} @> subquery.#{ltree_path_column}")

  where.not ltree_path_column => subquery
end
ltree_path() click to toggle source

Get lTree value

@return [String] ltree current value

# File lib/pg_ltree/model.rb, line 70
def ltree_path
  public_send ltree_path_column
end
ltree_path_before_last_save() click to toggle source

Get ltree original value before the save just occurred api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Dirty.html#method-i-attribute_before_last_save

@return [String] ltree previous value

# File lib/pg_ltree/model.rb, line 78
def ltree_path_before_last_save
  public_send :attribute_before_last_save, ltree_path_column
end
ltree_path_column() click to toggle source
# File lib/pg_ltree/model.rb, line 6
def ltree_path_column
  ltree_option_for :column
end
ltree_path_in_database() click to toggle source

Get lTree previous value originally attribute_was used in before create/update, destroy won’t call save so this work api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Dirty.html#method-i-attribute_in_database

@return [String] ltree value in database

# File lib/pg_ltree/model.rb, line 88
def ltree_path_in_database
  public_send :attribute_in_database, ltree_path_column
end
ltree_scope() click to toggle source

Get default scope of ltree

@return current class

# File lib/pg_ltree/model.rb, line 58
def ltree_scope
  self.class
end
parent() click to toggle source

Get parent of the node

return [Object] root node

# File lib/pg_ltree/model.rb, line 128
def parent
  ltree_scope.find_by "#{self.class.table_name}.#{ltree_path_column} = SUBPATH(?, 0, NLEVEL(?) - 1)", ltree_path,
    ltree_path
end
root() click to toggle source

Get root of the node

return [Object] root node

# File lib/pg_ltree/model.rb, line 121
def root
  ltree_scope.where("#{self.class.table_name}.#{ltree_path_column} = SUBPATH(?, 0, 1)", ltree_path).first
end
root?() click to toggle source

Check what current node is root

@return [Boolean] True - for root node, False - for childen node

# File lib/pg_ltree/model.rb, line 95
def root?
  depth == 1
end
roots() click to toggle source

Get roots

@return [ActiveRecord::Relation] relations of node’s roots

# File lib/pg_ltree/model.rb, line 13
def roots
  at_depth 1
end
self_and_ancestors() click to toggle source

Get self and ancestors

@return [ActiveRecord::Relation]

# File lib/pg_ltree/model.rb, line 151
def self_and_ancestors
  ltree_scope.where("#{self.class.table_name}.#{ltree_path_column} @> ?", ltree_path)
end
self_and_descendants() click to toggle source

Get self and descendants

@return [ActiveRecord::Relation]

# File lib/pg_ltree/model.rb, line 165
def self_and_descendants
  ltree_scope.where("#{self.class.table_name}.#{ltree_path_column} <@ ?", ltree_path)
end
self_and_siblings() click to toggle source

Get self and siblings

@return [ActiveRecord::Relation]

# File lib/pg_ltree/model.rb, line 179
def self_and_siblings
  ltree_scope.where(
    "SUBPATH(?, 0, NLEVEL(?) - 1) @> #{self.class.table_name}.#{ltree_path_column} AND nlevel(#{self.class.table_name}.#{ltree_path_column}) = NLEVEL(?)",
    ltree_path, ltree_path, ltree_path
  )
end
siblings() click to toggle source

Get siblings

@return [ActiveRecord::Relation]

# File lib/pg_ltree/model.rb, line 189
def siblings
  self_and_siblings.where.not ltree_path_column => ltree_path
end
where_path_liked(lquery) click to toggle source

Get all with nodes when path liked the lquery

@param lquery [String] ltree query @return [ActiveRecord::Relation] relations of node’

# File lib/pg_ltree/model.rb, line 41
def where_path_liked(lquery)
  where "#{table_name}.#{ltree_path_column} ~ ?", lquery
end
where_path_matches_ltxtquery(ltxtquery) click to toggle source

Get all nodes with path matching full-text-search-like pattern

@param ltxtquery [String] ltree search query @return [ActiveRecord::Relation] of matching nodes

# File lib/pg_ltree/model.rb, line 49
def where_path_matches_ltxtquery(ltxtquery)
  where "#{table_name}.#{ltree_path_column} @ ?", ltxtquery
end