Mongoid の recursively_embeds_many を使用して、ネストされたデータ ツリーを作成しています (Rails 3.2.8、Mongo 2.2、Mongoid 3.0.14、および Ryan Bates の nested_form gem 0.3.1)。これまでのところすべてが順調に進んでいますが、問題が発生し、特に、生成される配列のメンバーを並べ替える方法がわかりません。フロントエンドでフォームを操作するのに役立つJSが少しありますが、バックエンドでその新しい順序を表現する方法を理解できませんでした。これが私の主なモデルです:
class Navigator
include Mongoid::Document
include Mongoid::Timestamps
embeds_many :menu_items
accepts_nested_attributes_for :menu_items, :allow_destroy => true, :autosave => true
field :name
field :type
field :position
field :behavior
end
MenuItems モデルは次のとおりです。
class MenuItem
include Mongoid::Document
include Mongoid::Timestamps
recursively_embeds_many
accepts_nested_attributes_for :child_menu_items, :allow_destroy => true, :autosave => true
field :name
field :url
end
サーバーを監視すると、更新中に新しいアイテムが$push_all
メソッドを介して追加され、他のアイテムがネストされた配列メソッドに一致する $ 位置演算子を介して更新されていることがわかります (これはMongoid のJIRA SERVERの実装のようです)。 -851 回避策)。その結果、各 menu_item の位置は、入力された場所に基づいて常に固定されます。任意の数の順序付け属性と戦略を追加できることはわかっていますが、配列の順序をユーザーが課した順序を表すことができるため、これは Mongo では不要のようです。
Mongo に上記の制限があることは理解していますが、配列が更新されるたびに上書きする、つまり Mongo の$set
演算子を使用してその配列の既存の内容を置き換えることも合理的と思われます。ただし、Mongoid でこれを行う方法がわかりません。コントローラーを切り替えるのと同じくらい簡単かもしれないと思っていました
@tree.update_attributes(params[:tree])
に
@tree.set(params[:tree])
これにより、クエリは正しくフォーマットされますが、完全にエスケープされます。$unset
次に、最初にフィールドを削除して、フォームの非表示の id フィールドを削除できるのではないかと考えましたが、それも失敗します。
これはMongoの標準的な使用例のようですが、MongoidがMongo-yの方法でドキュメントを更新することを妨げているようにも思えます。また、Mongoid が演算子を使用できることも知っています。これは、タイムスタンプを使用するために追加された属性$set
を上書きするために使用されるためです。$ 位置演算子の回避策の代わりに、updated_at
単純に演算子を更新に使用するように Mongoid を構成できれば、問題はありません。$set
私はこれについて間違った方法で考えていますか、それとも何かが欠けていますか? 私の次のステップは、Mongo ドライバーに直接エスケープすることです。
ありがとう、カール
アップデート:
@tree.update_attribute(:tree, params[:tree])
正しいモペット出力を作成しますが、データは更新されません。配列の変更とは関係のないものを変更しても。
アップデート:
私は Mongoid ソリューションを理解できませんでしたが、jQuery ソリューションを理解することができました: jQuery UI ソートを使用した後、配列キーの名前を変更するために既にそれを使用していたので、乗り心地のためにいくつかのものを追加しました。すべてのアイテムのコピーを作成し、既存のアイテムを削除するように設定してから、コピーを新しいものとして追加します。フォームが送信されると、すべての古いものが最初に削除され、次にすべてのコピーがページ上の順序で新しいものとして追加されます。これは理想的な解決策ではありませんが、問題なく動作し、すべてのテクノロジの精神の範囲内にあると感じています。フォームはまだ一度にすべて処理されており、どのモデルにも外部の並べ替え属性を追加する必要はありません。JS がオフになっていると機能しませんが、ドラッグ アンド ドロップの並べ替えも機能しません。