Module: Ancestry::MaterializedPathPg

Defined in:
lib/ancestry/materialized_path_pg.rb

Instance Method Summary collapse

Instance Method Details

#update_descendants_hook(update_clause, old_ancestry, new_ancestry) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
# File 'lib/ancestry/materialized_path_pg.rb', line 30

def update_descendants_hook(update_clause, old_ancestry, new_ancestry)
  if self.class.respond_to?(:depth_cache_column)
    depth_cache_column = self.class.depth_cache_column
    depth_change = self.class.ancestry_depth_change(old_ancestry, new_ancestry)

    if depth_change != 0
      update_clause[depth_cache_column] = Arel.sql("#{depth_cache_column} + #{depth_change}")
    end
  end
  update_clause
end

#update_descendants_with_new_ancestry_sqlObject

Update descendants with new ancestry using a single SQL statement (after update)



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/ancestry/materialized_path_pg.rb', line 6

def update_descendants_with_new_ancestry_sql
  # If enabled and node is existing and ancestry was updated and the new ancestry is sane ...
  # The only way the ancestry could be bad is via `update_attribute` with a bad value
  if !ancestry_callbacks_disabled? && sane_ancestor_ids?
    old_ancestry = self.class.generate_ancestry(path_ids_before_last_save)
    new_ancestry = self.class.generate_ancestry(path_ids)
    # Replace old ancestry prefix with new ancestry:
    # CONCAT(new_ancestry, SUBSTRING(column, LENGTH(old_ancestry) + 1))
    column = self.class.ancestry_column
    replace_sql = self.class.concat("'#{new_ancestry}'", "SUBSTRING(#{column}, #{old_ancestry.length + 1})")
    update_clause = {
      column => Arel.sql(replace_sql)
    }

    current_time = current_time_from_proper_timezone
    timestamp_attributes_for_update_in_model.each do |column|
      update_clause[column] = current_time
    end

    update_descendants_hook(update_clause, old_ancestry, new_ancestry)
    unscoped_descendants_before_last_save.update_all update_clause
  end
end