You are viewing a read-only archive of the Blogs.Harvard network. Learn more.

Nested Sets and Scope

October 3rd, 2008

A colleague and I both had this same issue working with BNS and since there wasn’t much about it on the net, I figured I’d share.

Each TLD in my nested set will be its own tree root. And multiple tree roots in a nested set require a scope.


acts_as_nested_set :scope => :root

The ruby on rails wiki mentions scope using a root_id column, but you’ll notice in the example that the root records have a root_id of nil. This just doesn’t work.

When you attempt to move_to_child_of your new node record after create, you’ll recieve this error:

Impossible move, target node cannot be inside moved tree.

Now, we couldn’t find any documentation anywhere but after much trial and error my colleague discovered that populating the root_id of a root record with its own id, resolves the issue.


root = Domain.new
subdomains.each_with_index do |subdomain, index|
node = Domain.find_by_subdomain_and_parent_id(subdomain, parent.id)
if node.nil?
node = Domain.create(:subdomain => subdomain, root_id => root.id)
if parent.new_record? #is this a root record?
node.root_id = node.id # <-------------------------------- populate root for root records
node.save
root = node
else
node.move_to_child_of parent.id
end
end
parent = node
end

Entry Filed under: Ruby on Rails

2 Comments Add your own

  • 1. hades76  |  November 17th, 2008 at 6:31 pm

    I’m using the same plugin / method to create scope.
    And my database is good populate but how can i access a specific scope with full_set ?

    Actualy i use :
    MenuItem.root.full_set
    (who give me only scope = 1)

  • 2. Alex Schregardus  |  December 4th, 2008 at 10:04 am

    Try the following in your model, works from me.

    def before_create
    # Update the child object with its parents attrs
    unless self[:parent_id].to_i.zero?
    self[:root_id] = parent[:root_id].to_i
    end
    end

    def after_create
    # Update the parent root_id with its id
    if self[:parent_id].to_i.zero?
    self[:root_id] = self[:id]
    self.save
    else
    parent.add_child self
    end
    end

    See: http://i.nfectio.us/articles/2006/03/31/implement-acts_as_threaded-without-a-plugin

Leave a Comment

Required

Required, hidden

Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Trackback this post  |  Subscribe to the comments via RSS Feed


Pages

Meta

Recent Posts