如何使用RubyOnRails中的“充当嵌套集”创建可排序的接口

时间:2009-05-05 14:00:52

标签: ruby-on-rails ruby scriptaculous nested-sets

我一直在实现一些很好的交互式界面,可以在m rails应用程序中为使用acts_as_list的模型对列表进行排序。我有一个sort函数被调用,并使用sortable_element script.aculo.us函数设置每个拖放后每个记录的位置。

这是在拖放完成后处理排序的控制器操作的示例:

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

现在我正在尝试使用嵌套集(acts_as_nested_set)的模型做同样的事情。界面交互类型的一个示例:http://script.aculo.us/playground/test/functional/sortable_tree_test.html

我很困惑如何在拖放完成时编写控制器动作来处理排序。

到目前为止,我已将:tree => true参数添加到sortable _element函数中,它似乎发送了一个哈希列表,但似乎我仍然缺少有关整个嵌套订​​单的信息....

我确信之前已经完成过,并且不想尝试重新发明轮子,但我似乎无法找到控制器动作的任何示例< - >使用js函数设置查看以处理可排序的acts_as_nested_set

任何有关在rubyonrails中创建交互式可排序嵌套集的帮助都将不胜感激!

谢谢,

约翰

5 个答案:

答案 0 :(得分:2)

在此处查看示例应用 - http://github.com/matenia/jQuery-Awesome-Nested-Set-Drag-and-Drop

这是一种hacky方式,但基本上,先排序,然后保存顺序。 使用nestedsortables,serializelist和2个动作来遍历树

PS:我知道这个问题已经过了一年多了,但希望上面的链接可以帮助其他人来这里。

编辑:使用一些稍微清晰的代码添加了Rails3示例。

答案 1 :(得分:2)

来自http://henrik.nyh.se/2008/11/rails-jquery-sortables

的ONE sql-query的一个很好的解决方案
# in your model:

def self.order(ids)
  update_all(
    ['ordinal = FIND_IN_SET(id, ?)', ids.join(',')],
    { :id => ids }
  )
end

答案 2 :(得分:1)

刚刚发现:

github上的

sortable_element_for_nested_set

看起来它会完成这项工作,但是在尝试实现它时我遇到了一些错误。它基本上使javascript返回被移动的元素的id,然后遍历元素并返回其新的父,左和右值。不敢相信,这样的事情要花这么长时间才能写出来!幸运的是,就在我需要的时候:)

答案 3 :(得分:1)

以下是我项目中的一小段代码:

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

你在父母那里打电话给它,它会对孩子们进行排序。

您只需传递您从Sortable获得的值,如下所示:

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

希望这有帮助。

//拉斯

答案 4 :(得分:0)

the_sortable_tree

Rails 3.1 +的可排序嵌套集

梦想嵌套集的拖放?它应该与JQuery一起使用? 这是解决方案!