我使用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's implementation的JIRA SERVER-851 workaround。因此,每个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
运算符进行更新而不是使用$ position运算符解决方法,那么我将进行设置。我是在想这个错误的方法还是错过了什么?我的下一步是尝试直接进入Mongo驱动程序。
谢谢, 卡尔
更新
@tree.update_attribute(:tree, params[:tree])
创建正确的轻便摩托车输出,但数据不会更新。即使我改变了与修改数组无关的内容。
更新
虽然我无法弄清楚Mongoid解决方案,但我能够找到一个jQuery:我在使用jQuery UI排序后我已经用它来重命名数组键,所以我添加了几个东西为了骑。我复制了所有项目,将现有项目设置为删除,然后添加副本,就好像它们是新的一样。提交表单后,首先删除所有旧表单,然后按照页面上的顺序将所有副本添加为新表单。它不是一个理想的解决方案,但它工作正常,我感觉良好的所有技术的精神 - 表格仍在同时处理,我不需要添加外部排序属性任何型号。如果关闭JS,它将无法工作,但拖放排序也不会。