Module: ClosureTree::Finders

Extended by:
ActiveSupport::Concern
Defined in:
lib/closure_tree/finders.rb

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Instance Method Details

#find_all_by_generation(generation_level) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/closure_tree/finders.rb', line 32

def find_all_by_generation(generation_level)
  s = _ct.base_class.joins(<<-SQL)
    INNER JOIN (
      SELECT descendant_id
      FROM #{_ct.quoted_hierarchy_table_name}
      WHERE ancestor_id = #{_ct.quote(self.id)}
      GROUP BY 1
      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)
  SQL
  _ct.scope_with_order(s)
end

#find_by_path(path, attributes = {}) ⇒ Object

Find a child node whose ancestry_path minus self.ancestry_path is path.



6
7
8
9
# File 'lib/closure_tree/finders.rb', line 6

def find_by_path(path, attributes = {})
  return self if path.empty?
  self.class.find_by_path(path, attributes, id)
end

#find_or_create_by_path(path, attributes = {}, find_before_lock = true) ⇒ Object

Find a child node whose ancestry_path minus self.ancestry_path is path



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/closure_tree/finders.rb', line 12

def find_or_create_by_path(path, attributes = {}, find_before_lock = true)
  attributes[:type] ||= self.type if _ct.subclass? && _ct.has_type?
  (find_before_lock && find_by_path(path, attributes)) || begin
    _ct.with_advisory_lock do
      subpath = path.is_a?(Enumerable) ? path.dup : [path]
      child_name = subpath.shift
      return self unless child_name
      child = transaction do
        attrs = attributes.merge(_ct.name_sym => child_name)
        # shenanigans because children.create is bound to the superclass
        # (in the case of polymorphism):
        self.children.where(attrs).first || begin
          self.class.new(attrs).tap { |ea| self.children << ea }
        end
      end
      child.find_or_create_by_path(subpath, attributes, false)
    end
  end
end

#without_self(scope) ⇒ Object



45
46
47
# File 'lib/closure_tree/finders.rb', line 45

def without_self(scope)
  scope.without(self)
end