私は素晴らしいawesome_nestedセットで作られたカテゴリモデルを持っています. ドラッグ アンド ドロップ ツリーを正常に生成し、SERIALIZELIST プラグインを使用してこのツリーの完全なハッシュを正常に生成し、カテゴリ コントローラーに追加した「配列」メソッドに送信しました。(jqueryとnestedsortablesを使用)ログからのハッシュは次のようになります...
処理中 CategoriesController#array (2010-08-19 23:12:18 の 127.0.0.1 の場合) [POST] パラメータ: {"ul"=>{"0"=>{"class"=>"", "id" =>"category_1", "children"=>{"0"=>{"class"=>"", "id"=>"category_4", "children"=>{"0"=>{"class" =>"", "id"=>"category_3"}}}}}, "1"=>{"class"=>"", "id"=>"category_2", "children"=>{"0 "=>{"class"=>"", "id"=>"category_5"}, "1"=>{"class"=>"", "id"=>"category_6"}}}}}
私はソート機能に問題があります。
素晴らしいネストされたセットはいくつかの移動機能を提供しますが、私はそれについて理解できないようです。
ユーザーが保存を押したときにこのようなことをしたい(ところで、それはajaxリクエストを行い、上記のデータを正しく渡します)
def array
newlist = params[:ul]
newlist.each_with_index do |id, index, children|
#insert code here for saving the re-ordered array
end
render :nothing => true
end
これで十分な情報であり、誰かがこの質問に答えてくれることを願っています。
乾杯、
マテニア
----------- 更新と進行状況 -----------
数日前にこれを投稿して以来、開発環境で logger.info をいじって、舞台裏で何が起こっているかを確認しました。
私は2つの関数を書くことになりました。1 つは配列のルートを通過し、もう 1 つは子と子の子を再帰的に移動します。しかし、これはあまりにも多くのデータベース呼び出しで終わります (しかし、それを行う方法は他にないかもしれません)。
コードは次のようになります...
def array
# fetch the current tree
@allcategories = Category.all
# assign the sorted tree to a variable
newlist = params[:ul]
# initialize the previous item
previous = nil
#loop through each item in the new list (passed via ajax)
newlist.each_with_index do |array, index|
# get the category id of the item being moved
moved_item_id = array[1][:id].split(/category_/)
# find the object that is being moved (in database)
@current_category = Category.find_by_id(moved_item_id)
# if this is the first item being moved, move it to the root.
unless previous.nil?
@previous_item = Category.find_by_id(previous)
@current_category.move_to_right_of(@previous_item)
else
@current_category.move_to_root
end
# then, if this item has children we need to loop through them
unless array[1][:children].blank?
# unless there are no children in the array, send it to the recursive children function
childstuff(array[1], @current_category)
end
# set previous to the last moved item, for the next round
previous = moved_item_id
end
render :nothing => true
end
def childstuff(node, category)
# find the category that has been passed into the function
@selected_category = Category.find(category)
for child in node[:children]
child_id = child[1][:id].split(/category_/)
child_category = Category.find_by_id(child_id)
child_category.move_to_child_of(@selected_category)
#if this child has children -- run recursion on this function
unless child[1][:children].blank?
childstuff(child[1], child_category)
end
end
end
これをより効率的にする方法と、データベース呼び出しの数を減らす方法について、誰かが光を当ててくれることを願っています。私は他の関数を書くことを考えましたが、それらはすべて同じことをするつもりです。
この特定のプロジェクトでは、100 以上の異なるカテゴリがあるとは思いません。これは最善の方法ではありませんが、うまくいきます。
再び乾杯、
マテニア
最終的な回避策
上記のコードで、子が適切に保存されないという問題がありました。これが私の最新の試みで、うまくいくようです。
def array
# assign the sorted tree to a variable
newlist = params[:ul]
# initialize the previous item
previous = nil
#loop through each item in the new list (passed via ajax)
newlist.each_with_index do |array, index|
# get the category id of the item being moved
moved_item_id = array[1][:id].split(/category_/)
# find the object that is being moved (in database)
@current_category = Category.find_by_id(moved_item_id)
# if this is the first item being moved, move it to the root.
unless previous.nil?
@previous_item = Category.find_by_id(previous)
@current_category.move_to_right_of(@previous_item)
else
@current_category.move_to_root
end
# then, if this item has children we need to loop through them
unless array[1][:children].blank?
# NOTE: unless there are no children in the array, send it to the recursive children function
childstuff(array[1], @current_category)
end
# set previous to the last moved item, for the next round
previous = moved_item_id
end
Category.rebuild!
render :nothing => true
end
def childstuff(mynode, category)
# logger.info "node = #{node} caegory = #{category}"
#loop through it's children
for child in mynode[:children]
# get the child id from each child passed into the node (the array)
child_id = child[1][:id].split(/category_/)
#find the matching category in the database
child_category = Category.find_by_id(child_id)
#move the child to the selected category
child_category.move_to_child_of(category)
# loop through the children if any
unless child[1][:children].blank?
# if there are children - run them through the same process
childstuff(child[1], child_category)
end
end
end
それでもデータベース呼び出しが多すぎますが、データベース内の各アイテムを再記録する必要があるため、この機能が必要なための代償だと思います。
これが困っている人に役立つことを願っています。誰かがこれについて助けを求めている場合は、遠慮なく私にメッセージを送ってください。
すばらしいネストされたセット + JQUERY ドラッグ アンド ドロップ + SERIALIZELIST プラグイン ....
乾杯、
マテニア