Module: ActiveRecordExtended::Ltree

Defined in:
lib/active_record_extended/ltree_query_methods.rb

Overview

Extends ActiveRecord with ltree query helpers.

WHERE clause operators (<@, @>, ~) are handled by Arel predicates in
config/initializers/arel_ltree_predicates.rb. Use those instead:

Item.where(Item[:pc_path_slugs].ltree_descendant('goods.controls'))
Item.where.not(Item[:pc_path_slugs].ltree_descendant('goods.publications'))
ProductLine.where(ProductLine[:ltree_path_ids].ltree_ancestor('1.2.3'))
ProductLine.where(ProductLine[:ltree_path_slugs].ltree_matches('.tempzone.'))

This file provides:

  • where.ltree_contains -- index()-based containment (no Arel equivalent)
  • where.ltree_depth -- nlevel()-based depth filter
  • Ltree module -- Arel function helpers (nlevel, subpath, lca, etc.)
  • LtreeSelectMethods -- select_ltree_depth, select_ltree_root, etc.
  • order_by_ltree_depth

Arel helpers for ltree functions - can be used in complex queries

Class Method Summary collapse

Class Method Details

.index(column, search) ⇒ Arel::Nodes::NamedFunction

index(ltree, ltree) - Returns position of first occurrence of second argument.
search is properly quoted via the AR connection so callers can pass
untrusted strings safely — Brakeman flags raw Arel.sql("'#{x}'") as
SQL-injection (correctly).

Returns:

  • (Arel::Nodes::NamedFunction)

    the index() function node



51
52
53
54
# File 'lib/active_record_extended/ltree_query_methods.rb', line 51

def index(column, search)
  quoted_search = ActiveRecord::Base.lease_connection.quote(search.to_s)
  Arel::Nodes::NamedFunction.new('index', [Arel.sql(column.to_s), Arel.sql(quoted_search)])
end

.lca(*columns) ⇒ Arel::Nodes::NamedFunction

lca(ltree, ltree, ...) - Returns longest common ancestor of paths

Returns:

  • (Arel::Nodes::NamedFunction)

    the lca() function node



41
42
43
44
# File 'lib/active_record_extended/ltree_query_methods.rb', line 41

def lca(*columns)
  args = columns.map { |c| Arel.sql(c.to_s) }
  Arel::Nodes::NamedFunction.new('lca', args)
end

.ltree2text(column) ⇒ Arel::Nodes::NamedFunction

ltree2text(ltree) - Converts ltree to text

Returns:

  • (Arel::Nodes::NamedFunction)

    the ltree2text() function node



66
67
68
# File 'lib/active_record_extended/ltree_query_methods.rb', line 66

def ltree2text(column)
  Arel::Nodes::NamedFunction.new('ltree2text', [Arel.sql(column.to_s)])
end

.nlevel(column) ⇒ Arel::Nodes::NamedFunction

nlevel(ltree) - Returns the number of labels in the path

Returns:

  • (Arel::Nodes::NamedFunction)

    the nlevel() function node



27
28
29
# File 'lib/active_record_extended/ltree_query_methods.rb', line 27

def nlevel(column)
  Arel::Nodes::NamedFunction.new('nlevel', [Arel.sql(column.to_s)])
end

.subpath(column, offset, len = nil) ⇒ Arel::Nodes::NamedFunction

subpath(ltree, offset, len) - Extracts subpath starting at offset for len labels

Returns:

  • (Arel::Nodes::NamedFunction)

    the subpath() function node



33
34
35
36
37
# File 'lib/active_record_extended/ltree_query_methods.rb', line 33

def subpath(column, offset, len = nil)
  args = [Arel.sql(column.to_s), Arel.sql(offset.to_s)]
  args << Arel.sql(len.to_s) if len
  Arel::Nodes::NamedFunction.new('subpath', args)
end

.text2ltree(value) ⇒ Arel::Nodes::NamedFunction

text2ltree(text) - Converts text to ltree. value is properly quoted
so untrusted strings can be passed through safely.

Returns:

  • (Arel::Nodes::NamedFunction)

    the text2ltree() function node



59
60
61
62
# File 'lib/active_record_extended/ltree_query_methods.rb', line 59

def text2ltree(value)
  quoted_value = ActiveRecord::Base.lease_connection.quote(value.to_s)
  Arel::Nodes::NamedFunction.new('text2ltree', [Arel.sql(quoted_value)])
end