module CollectiveIdea::Acts::NestedSet::Model::Prunable

Public Instance Methods

decendants_to_destroy_in_order() click to toggle source

Use reverse to delete from deepest child to parent in order to respect any possible foreign keys

   # File lib/awesome_nested_set/model/prunable.rb
39 def decendants_to_destroy_in_order
40   descendants.reverse
41 end
destroy_descendants() click to toggle source

Prunes a branch off of the tree, shifting all of the elements on the right back to the left so the counts still work.

   # File lib/awesome_nested_set/model/prunable.rb
 9 def destroy_descendants
10   return if right.nil? || left.nil? || skip_before_destroy
11 
12   in_tenacious_transaction do
13     # Rescue from +ActiveRecord::RecordNotFound+ error as there may be a case
14     # that an +object+ has already been destroyed by its parent, but objects that are
15     # in memory are not aware about this.
16     begin
17       reload_nested_set
18     rescue ActiveRecord::RecordNotFound
19       self.skip_before_destroy = true
20       return true
21     end
22     # select the rows in the model that extend past the deletion point and apply a lock
23     nested_set_scope.right_of(left).select(primary_id).lock(true)
24 
25     return false unless destroy_or_delete_descendants
26 
27     # update lefts and rights for remaining nodes
28     update_siblings_for_remaining_nodes
29 
30     # Reload is needed because children may have updated their parent (self) during deletion.
31     reload
32 
33     # Don't allow multiple calls to destroy to corrupt the set
34     self.skip_before_destroy = true
35   end
36 end
destroy_or_delete_descendants() click to toggle source
   # File lib/awesome_nested_set/model/prunable.rb
43 def destroy_or_delete_descendants
44   if acts_as_nested_set_options[:dependent] == :destroy
45     decendants_to_destroy_in_order.each do |model|
46       model.skip_before_destroy = true
47       model.destroy
48     end
49   elsif acts_as_nested_set_options[:dependent] == :restrict_with_exception
50     raise ActiveRecord::DeleteRestrictionError.new(:children) unless leaf?
51     return true
52   elsif acts_as_nested_set_options[:dependent] == :restrict_with_error
53     unless leaf?
54       record = self.class.human_attribute_name(:children).downcase
55       if Rails::VERSION::MAJOR < 5
56         errors.add(:base, :"restrict_dependent_destroy.many", record: record)
57         return false
58       else
59         errors.add(:base, :"restrict_dependent_destroy.has_many", record: record)
60         throw :abort
61       end
62     end
63     return true
64    elsif acts_as_nested_set_options[:dependent] == :nullify
65      descendants.update_all(parent_column_name => nil)
66    else
67     descendants.delete_all
68   end
69 end
diff() click to toggle source
   # File lib/awesome_nested_set/model/prunable.rb
84 def diff
85   right - left + 1
86 end
update_siblings(direction) click to toggle source
   # File lib/awesome_nested_set/model/prunable.rb
76 def update_siblings(direction)
77   full_column_name = send("quoted_#{direction}_column_full_name")
78   column_name = send("quoted_#{direction}_column_name")
79 
80   nested_set_scope.where(["#{full_column_name} > ?", right]).
81     update_all(["#{column_name} = (#{column_name} - ?)", diff])
82 end
update_siblings_for_remaining_nodes() click to toggle source
   # File lib/awesome_nested_set/model/prunable.rb
71 def update_siblings_for_remaining_nodes
72   update_siblings(:left)
73   update_siblings(:right)
74 end