【问题标题】:Mongoid: Changing the order of documents in an embeds_many relationMongoid:更改 embeds_many 关系中文档的顺序
【发布时间】:2011-08-16 18:21:20
【问题描述】:

我有一个 mongoid 文档,它嵌入了其他具有类似关系的文档 这个:

embeds_many :blocks

创建新块工作正常,但我无法设法更改 现有嵌入文档的顺序。例如我有三个 嵌入块,我想将最后一个移到第一个 位置。这样做的正确方法是什么?

【问题讨论】:

    标签: ruby-on-rails-3 mongoid


    【解决方案1】:

    我不得不使用 mongoid 的 recursively_embeds_many 功能来处理这个问题,但它本质上是相同的。据我所知,从字面上重写文档并没有错。编写一个模型方法来做类似的事情:

    def reverse_blocks
      reversed_blocks = blocks.to_a.reverse
      blocks.clear
      reversed_blocks.each do |b|
        blocks.create b.attributes
      end
      save
    end
    

    上面的代码不是很好,但它让你知道如何做你想做的事。我对仅仅为了重新排列数组中的东西而不得不经历这些并不感到兴奋,但它就是这样。

    【讨论】:

    • 这似乎不起作用(不再?-我正在使用 mongoid 3.0.9)。如果不复制 b.attributes,我会因为冻结的哈希而出错。然后我遇到了 _id/_type 无法访问(attr_accessible)的问题。所以我需要禁用批量分配保护(无论如何我都不想要)
    • 你可能是对的。这肯定是在 Mongoid 2 上发现的。您将希望将 b.attributes 设置为仅要复制的字段,而忽略 _id、_type 等。attributes 方法在 3 中的工作方式必须不同,我可以只是假设。
    • 如果您想保留受保护的属性(_id、_type 等...),您需要明确设置这些属性。例如:new_block = blocks.build(b.attributes)new_block._id = b._idnew_block.save
    【解决方案2】:

    我认为,真正正确的方法是在您的嵌入式文档字段“权重”中创建并使用 asc(:weight) 或 desc(:weight) 查询它们。您不依赖于持久的非嵌入文档的顺序,因此您不应该嵌入。

    但如果你迫切需要这样做,你在 mongoid 中嵌入的文档只是数组,所以你可以这样做:

    doc.embedded_docs = [doc.embedded_docs.last] + doc.embedded_docs[0..-2]
    

    【讨论】:

    • 我试过了,但是之后数组是空的!?如果我尝试“反向”或类似的东西,我也会看到这种行为。使用 :weight 不是一种选择。我使用 MongoDB 是因为我不想以“SQL 方式”来做。 ;-)
    • 我从 mongodb 列表中得到了反馈。无法移动单个数组元素。必须重写文档,但对于 Mongoid 和嵌入式文档来说,这似乎是不可能的。因此,您使用重量/排序的解决方案似乎是最好的解决方案 - 即使我不喜欢它。 :-/
    • 实际上 MongoDB 并不是一个纯粹的 NoSQL 解决方案,而是一种关系型和 NoSQL 方法的混合体。所以我认为,这种方法是相当有效的。
    猜你喜欢
    • 1970-01-01
    • 2012-01-16
    • 1970-01-01
    • 2012-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    相关资源
    最近更新 更多