Method: Ancestry::ClassMethods#restore_ancestry_integrity!

Defined in:
lib/ancestry/class_methods.rb

#restore_ancestry_integrity!Object

Integrity restoration



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/ancestry/class_methods.rb', line 174

def restore_ancestry_integrity!
  parent_ids = {}
  # Wrap the whole thing in a transaction ...
  ancestry_base_class.transaction do
    unscoped_where do |scope|
      # For each node ...
      scope.find_each do |node|
        # ... set its ancestry to nil if invalid
        if !node.sane_ancestor_ids?
          node.without_ancestry_callbacks do
            node.update_attribute :ancestor_ids, []
          end
        end
        # ... save parent id of this node in parent_ids array if it exists
        parent_ids[node.id] = node.parent_id if exists? node.parent_id

        # Reset parent id in array to nil if it introduces a cycle
        parent_id = parent_ids[node.id]
        until parent_id.nil? || parent_id == node.id
          parent_id = parent_ids[parent_id]
        end
        parent_ids[node.id] = nil if parent_id == node.id
      end

      # For each node ...
      scope.find_each do |node|
        # ... rebuild ancestry from parent_ids array
        ancestor_ids, parent_id = [], parent_ids[node.id]
        until parent_id.nil?
          ancestor_ids, parent_id = [parent_id] + ancestor_ids, parent_ids[parent_id]
        end
        node.without_ancestry_callbacks do
          node.update_attribute :ancestor_ids, ancestor_ids
        end
      end
    end
  end
end