lib/closure_tree/finders.rb in closure_tree-6.6.0 vs lib/closure_tree/finders.rb in closure_tree-7.0.0

- old
+ new

@@ -39,11 +39,11 @@ SELECT descendant_id FROM #{_ct.quoted_hierarchy_table_name} WHERE ancestor_id = #{_ct.quote(self.id)} GROUP BY descendant_id HAVING MAX(#{_ct.quoted_hierarchy_table_name}.generations) = #{generation_level.to_i} - ) AS descendants ON (#{_ct.quoted_table_name}.#{_ct.base_class.primary_key} = descendants.descendant_id) + ) #{ _ct.t_alias_keyword } descendants ON (#{_ct.quoted_table_name}.#{_ct.base_class.primary_key} = descendants.descendant_id) SQL _ct.scope_with_order(s) end def without_self(scope) @@ -74,11 +74,11 @@ INNER JOIN ( SELECT ancestor_id FROM #{_ct.quoted_hierarchy_table_name} GROUP BY ancestor_id HAVING MAX(#{_ct.quoted_hierarchy_table_name}.generations) = 0 - ) AS leaves ON (#{_ct.quoted_table_name}.#{primary_key} = leaves.ancestor_id) + ) #{ _ct.t_alias_keyword } leaves ON (#{_ct.quoted_table_name}.#{primary_key} = leaves.ancestor_id) SQL _ct.scope_with_order(s.readonly(false)) end def with_ancestor(*ancestors) @@ -88,41 +88,51 @@ where("#{_ct.hierarchy_table_name}.generations > 0"). readonly(false) _ct.scope_with_order(scope) end + def with_descendant(*descendants) + descendant_ids = descendants.map { |ea| ea.is_a?(ActiveRecord::Base) ? ea._ct_id : ea } + scope = descendant_ids.blank? ? all : joins(:descendant_hierarchies). + where("#{_ct.hierarchy_table_name}.descendant_id" => descendant_ids). + where("#{_ct.hierarchy_table_name}.generations > 0"). + readonly(false) + _ct.scope_with_order(scope) + end + def find_all_by_generation(generation_level) s = joins(<<-SQL.strip_heredoc) INNER JOIN ( SELECT #{primary_key} as root_id FROM #{_ct.quoted_table_name} WHERE #{_ct.quoted_parent_column_name} IS NULL - ) AS roots ON (1 = 1) + ) #{ _ct.t_alias_keyword } roots ON (1 = 1) INNER JOIN ( SELECT ancestor_id, descendant_id FROM #{_ct.quoted_hierarchy_table_name} GROUP BY ancestor_id, descendant_id HAVING MAX(generations) = #{generation_level.to_i} - ) AS descendants ON ( + ) #{ _ct.t_alias_keyword } descendants ON ( #{_ct.quoted_table_name}.#{primary_key} = descendants.descendant_id AND roots.root_id = descendants.ancestor_id ) SQL _ct.scope_with_order(s) end # Find the node whose +ancestry_path+ is +path+ def find_by_path(path, attributes = {}, parent_id = nil) + return nil if path.blank? path = _ct.build_ancestry_attr_path(path, attributes) if path.size > _ct.max_join_tables return _ct.find_by_large_path(path, attributes, parent_id) end scope = where(path.pop) last_joined_table = _ct.table_name path.reverse.each_with_index do |ea, idx| next_joined_table = "p#{idx}" scope = scope.joins(<<-SQL.strip_heredoc) - INNER JOIN #{_ct.quoted_table_name} AS #{next_joined_table} + INNER JOIN #{_ct.quoted_table_name} #{ _ct.t_alias_keyword } #{next_joined_table} ON #{next_joined_table}.#{_ct.quoted_id_column_name} = #{connection.quote_table_name(last_joined_table)}.#{_ct.quoted_parent_column_name} SQL scope = _ct.scoped_attributes(scope, ea, next_joined_table) last_joined_table = next_joined_table