How to create a sortable interface with "acts as a nested set" in RubyOnRails

I have implemented some nice interactive interfaces that can sort lists in my m rails application for models that use acts_as_list . I have a sort function that is called and sets the position for each record after each drag using the sortable_element script.aculo.us function.

This is an example of a controller action that handles sorting after the drag and drop is completed:

  def sort params[:documents].each_with_index do |id, index| Document.update_all(['position=?', index+1], ['id=?', id]) end end 

Now I'm trying to do the same with the model, which is a nested set ( acts_as_nested_set ). An example of an interface interaction type: http://script.aculo.us/playground/test/functional/sortable_tree_test.html

I was fixated on how to write a controller action to handle sorting when dragging is completed.

I added a parameter: tree => true for the sortable _element function so far, which seems to send a list of hashes, but it seems like I still lack information about the entire nested order ....

I was sure that this was done earlier and did not want to try to reinvent the wheel, but I can not find any examples of the ↔ view controller action with js function setting to handle sortable acts_as_nested_set

Any help on creating an interactive sortable nested set in rubyonrails would be appreciated!

Thanks,

John

+6
ruby ruby-on-rails nested-sets scriptaculous
source share
5 answers

see an example here - http://github.com/matenia/jQuery-Awesome-Nested-Set-Drag-and-Drop

This is a hacker way to do this, but basically, sort first and then keep order. Uses file attachments, serialized and 2 actions to move the tree

PS: I know this question is older than a year, but hoping the link above helps someone else come here.

edit: added Rails3 example with slightly cleaner code.

+2
source share

good solution with one SQL query from http://henrik.nyh.se/2008/11/rails-jquery-sortables

 # in your model: def self.order(ids) update_all( ['ordinal = FIND_IN_SET(id, ?)', ids.join(',')], { :id => ids } ) end 
+2
source share

Just found this:

sortable_element_for_nested_set on github

This seems to work, however, I have some errors trying to implement it. This basically causes javascript to return the id of the element that was moved, then iterates through the elements and returns its new parent, left and right values. I can’t believe it took a long time for something like this to be written! Fortunately, this was exactly when I needed it :)

+1
source share

Here is a snippet of code from my project that does the trick:

http://gist.github.com/659532

  def reorder_children(ordered_ids) ordered_ids = ordered_ids.map(&:to_i) current_ids = children.map(&:id) unless current_ids - ordered_ids == [] && ordered_ids - current_ids == [] raise ArgumentError, "Not ordering the same ids that I have as children. My children: #{current_ids.join(", ")}. Your list: #{ordered_ids.join(", ")}. Difference: #{(current_ids - ordered_ids).join(', ')} / #{(ordered_ids - current_ids).join(', ')}" end j = 0 transaction do for new_id in ordered_ids old_id = current_ids[j] if new_id == old_id j += 1 else Category.find(new_id).move_to_left_of(old_id) current_ids.delete(new_id) end end end end 

You call it on the parent and sort it.

You just pass the value you get from Sortable, for example:

  def reorder @category.reorder_children(params[:categories]) render :nothing => true end 

Hope this helps.

// Lars

+1
source share

the_sortable_tree

Sortable Nesting Kit for Rails 3.1 +

Dreaming of drag and drop for nested sets? Should it be with jQuery? This is the solution!

0
source share

All Articles