Created
March 10, 2011 19:13
-
-
Save tpinto/864699 to your computer and use it in GitHub Desktop.
awesome nested set, .rebuild! method fully commented (WIP)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Rebuilds the left & rights if unset or invalid. Also very useful for converting from acts_as_tree. | |
def rebuild! | |
# Don't rebuild a valid tree. | |
return true if valid? | |
# defines the method _scope_ to return _nil_ | |
scope = lambda{|node|} | |
# if the _:scope_ option was set, we must use it | |
if acts_as_nested_set_options[:scope] | |
# redefine the _scope_ method | |
scope = lambda{|node| | |
# scope_column_names is an Array of scopes | |
scope_column_names.inject(""){|str, column_name| | |
# we go through all scopes and add them to a string that will be used on _:conditions_ | |
# example: if _:scope_ was defined as _:company_, _:company_id_ will be used and this will return the following string: | |
# "AND company_id = 5" | |
# (ignoring db quoting stuff and assuming the passed node's company_id is _5_) | |
str << "AND #{connection.quote_column_name(column_name)} = #{connection.quote(node.send(column_name.to_sym))} " | |
} | |
} | |
end | |
indices = {} | |
# define the +set_left_and_rights+ method (returns true if the +node.save!+ succeeds) | |
set_left_and_rights = lambda do |node| | |
# set left | |
node[left_column_name] = indices[scope.call(node)] += 1 | |
# find sub-nodes and set left/right for them | |
find( | |
:all, | |
:conditions => ["#{quoted_parent_column_name} = ? #{scope.call(node)}", node], | |
:order => "#{quoted_left_column_name}, #{quoted_right_column_name}, id" | |
).each{|n| set_left_and_rights.call(n) } | |
# set right | |
node[right_column_name] = indices[scope.call(node)] += 1 | |
# save node | |
node.save! | |
end | |
# Find root node(s) | |
root_nodes = find( | |
:all, | |
:conditions => "#{quoted_parent_column_name} IS NULL", | |
:order => "#{quoted_left_column_name}, #{quoted_right_column_name}, id" | |
).each do |root_node| | |
# setup index for this scope | |
indices[scope.call(root_node)] ||= 0 | |
set_left_and_rights.call(root_node) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment