1

我正在使用 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方法添加新项目,并通过匹配嵌套数组方法的 $ 位置运算符更新其他项目(这看起来是MongoidJIRA 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 它将无法工作,但拖放排序也不会。

4

0 回答 0