Class: RecursiveTreeScopes::Scopes

Inherits:
Object
  • Object
show all
Defined in:
lib/activerecord-recursive_tree_scopes.rb

Class Method Summary collapse

Class Method Details

.ancestors_for(instance, key) ⇒ Object



34
35
36
# File 'lib/activerecord-recursive_tree_scopes.rb', line 34

def ancestors_for(instance, key)
  instance.class.where("#{instance.class.table_name}.id IN (#{ancestors_sql_for instance, key})").order("#{instance.class.table_name}.id")
end

.ancestors_sql_for(instance, key) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/activerecord-recursive_tree_scopes.rb', line 38

def ancestors_sql_for(instance, key)
  keys = [ key ].flatten
  tree_sql =  "    WITH RECURSIVE ancestor_search(id, \#{keys.join ', '}, path) AS (\n        SELECT id, \#{keys.join ', '}, ARRAY[id]\n          FROM \#{instance.class.table_name}\n          WHERE id = \#{instance.id}\n      UNION ALL\n        SELECT \#{instance.class.table_name}.id, \#{keys.collect{|key| \"\#{instance.class.table_name}.\#{key}\" }.join ', '}, path || \#{instance.class.table_name}.id\n          FROM \#{instance.class.table_name}, ancestor_search\n          WHERE \#{keys.collect{ |key| \"ancestor_search.\#{key} = \#{instance.class.table_name}.id\" }.join ' OR '}\n      )\n    SELECT id\n      FROM ancestor_search\n      WHERE id != \#{instance.id}\n      ORDER BY array_length(path, 1), path\n  SQL\n  tree_sql.gsub(/\\s{2,}/, ' ')\nend\n"

.descendants_for(instance, key) ⇒ Object



58
59
60
# File 'lib/activerecord-recursive_tree_scopes.rb', line 58

def descendants_for(instance, key)
  instance.class.where("#{instance.class.table_name}.id IN (#{descendants_sql_for instance, key})").order("#{instance.class.table_name}.id")
end

.descendants_sql_for(instance, key) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/activerecord-recursive_tree_scopes.rb', line 62

def descendants_sql_for(instance, key)
  keys = [ key ].flatten
  tree_sql =  "    WITH RECURSIVE descendants_search(id, path) AS (\n        SELECT id, ARRAY[id]\n        FROM \#{instance.class.table_name}\n        WHERE id = \#{instance.id}\n      UNION ALL\n        SELECT \#{instance.class.table_name}.id, path || \#{instance.class.table_name}.id\n        FROM descendants_search\n        JOIN \#{instance.class.table_name}\n        ON \#{keys.collect{ |key| \"descendants_search.id = \#{instance.class.table_name}.\#{key}\" }.join ' OR '}\n        WHERE NOT \#{instance.class.table_name}.id = ANY(path)\n    )\n    SELECT id\n      FROM descendants_search\n      WHERE id != \#{instance.id}\n      ORDER BY array_length(path, 1), path\n  SQL\n  tree_sql.gsub(/\\s{2,}/, ' ')\nend\n"