ruby-on-railsacts-as-tree

Why do my root nodes end up with themselves as the parent_id with acts_as_tree?


I have an existing tree structure to which I'd like to add a new root and move the existing roots down one. I've written a rake task which works fine apart from one thing.

The new root ends up with a parent_id which matches it's new id instead of NULL. The existing roots are successfully changed to have the new root as a parent.

# Rake task
desc "Change categories to use new root"
task :make_new_category_root => :environment do
  Company.all.each do |company|
    current_roots = company.root_categories
    new_root = Category.new(name: "New root")
    new_root.company = company
    new_root.parent = nil
    if new_root.save
      current_roots.each do |current|
        current.parent = new_root
        current.save
      end
    end
  end

# Category class, abbreviated
class Category < ActiveRecord::Base
  include ActsAsTree
  acts_as_tree :order => "name"

  belongs_to :company, touch: true
  validates :name, uniqueness: { scope: :company_id }, :if => :root?      
  scope :roots, where(:parent_id => nil)      
end

Solution

  • I would need to see Company#root_categories to be sure, however I predict that root_categories in-fact includes new_root.

    Is is due to the lazy evaluation of queries in Rails.

    Try changing:

    current_roots = company.root_categories
    

    to:

    current_roots = company.root_categories.all