module Ancestry::MaterializedPath
store ancestry as grandparent_id/parent_id root a=nil,id=1 children=id,id/% == 1, 1/% 3: a=1/2,id=3 children=a/id,a/id/% == 1/2/3, 1/2/3/%
Public Class Methods
extended(base)
click to toggle source
# File lib/ancestry/materialized_path.rb, line 6 def self.extended(base) base.send(:include, InstanceMethods) end
Public Instance Methods
ancestors_of(object)
click to toggle source
# File lib/ancestry/materialized_path.rb, line 18 def ancestors_of(object) t = arel_table node = to_node(object) where(t[primary_key].in(node.ancestor_ids)) end
ancestry_root()
click to toggle source
# File lib/ancestry/materialized_path.rb, line 91 def ancestry_root nil end
children_of(object)
click to toggle source
# File lib/ancestry/materialized_path.rb, line 30 def children_of(object) t = arel_table node = to_node(object) where(t[ancestry_column].eq(node.child_ancestry)) end
descendant_before_save_conditions(object)
click to toggle source
# File lib/ancestry/materialized_path.rb, line 57 def descendant_before_save_conditions(object) node = to_node(object) descendants_by_ancestry( node.child_ancestry_before_save ) end
descendant_conditions(object)
click to toggle source
# File lib/ancestry/materialized_path.rb, line 52 def descendant_conditions(object) node = to_node(object) descendants_by_ancestry( node.child_ancestry ) end
descendants_by_ancestry(ancestry)
click to toggle source
# File lib/ancestry/materialized_path.rb, line 47 def descendants_by_ancestry(ancestry) t = arel_table t[ancestry_column].matches("#{ancestry}#{ancestry_delimiter}%", nil, true).or(t[ancestry_column].eq(ancestry)) end
descendants_of(object)
click to toggle source
# File lib/ancestry/materialized_path.rb, line 43 def descendants_of(object) where(descendant_conditions(object)) end
indirects_of(object)
click to toggle source
indirect = anyone who is a descendant, but not a child
# File lib/ancestry/materialized_path.rb, line 37 def indirects_of(object) t = arel_table node = to_node(object) where(t[ancestry_column].matches("#{node.child_ancestry}#{ancestry_delimiter}%", nil, true)) end
inpath_of(object)
click to toggle source
# File lib/ancestry/materialized_path.rb, line 24 def inpath_of(object) t = arel_table node = to_node(object) where(t[primary_key].in(node.path_ids)) end
ordered_by_ancestry(order = nil)
click to toggle source
# File lib/ancestry/materialized_path.rb, line 74 def ordered_by_ancestry(order = nil) if %w(mysql mysql2 sqlite sqlite3).include?(connection.adapter_name.downcase) reorder(arel_table[ancestry_column], order) elsif %w(postgresql oracleenhanced).include?(connection.adapter_name.downcase) && ActiveRecord::VERSION::STRING >= "6.1" reorder(Arel::Nodes::Ascending.new(arel_table[ancestry_column]).nulls_first, order) else reorder( Arel::Nodes::Ascending.new(Arel::Nodes::NamedFunction.new('COALESCE', [arel_table[ancestry_column], Arel.sql("''")])), order ) end end
ordered_by_ancestry_and(order)
click to toggle source
# File lib/ancestry/materialized_path.rb, line 87 def ordered_by_ancestry_and(order) ordered_by_ancestry(order) end
path_of(object)
click to toggle source
# File lib/ancestry/materialized_path.rb, line 10 def path_of(object) to_node(object).path end
roots()
click to toggle source
# File lib/ancestry/materialized_path.rb, line 14 def roots where(arel_table[ancestry_column].eq(ancestry_root)) end
siblings_of(object)
click to toggle source
# File lib/ancestry/materialized_path.rb, line 68 def siblings_of(object) t = arel_table node = to_node(object) where(t[ancestry_column].eq(node[ancestry_column].presence)) end
subtree_of(object)
click to toggle source
# File lib/ancestry/materialized_path.rb, line 62 def subtree_of(object) t = arel_table node = to_node(object) descendants_of(node).or(where(t[primary_key].eq(node.id))) end
Private Instance Methods
ancestry_format_regexp()
click to toggle source
# File lib/ancestry/materialized_path.rb, line 108 def ancestry_format_regexp /\A#{ancestry_primary_key_format}(#{Regexp.escape(ancestry_delimiter)}#{ancestry_primary_key_format})*\z/.freeze end
ancestry_nil_allowed?()
click to toggle source
# File lib/ancestry/materialized_path.rb, line 104 def ancestry_nil_allowed? true end
ancestry_validation_options()
click to toggle source
# File lib/ancestry/materialized_path.rb, line 97 def ancestry_validation_options { format: { with: ancestry_format_regexp }, allow_nil: ancestry_nil_allowed? } end