1

我在更新 Ruby / Sinatra 应用程序中的嵌入式文档时遇到问题。我试图在更新语句中使用位置运算符“$”,以便从嵌入式数组中选择正确的文档。但这会引发“ArgumentError - 参数数量错误(2 比 1)”错误。

带有硬编码数组索引的简单更新语句可以正常工作。所以也许 Mongoid/Moped 不支持位置运算符?...虽然从我所见,它看起来应该。

有谁知道最好的方法是什么?是否有其他方法可以确定子文档索引,而无需在我的控制器中使用 Ruby 遍历它们——这是 B 计划,但看起来真的很不稳定!...

这是我的基本设置:我有“客户”...

class Customer
    include Mongoid::Document
    field :customer_name, type: String

    embeds_many :contacts

    attr_accessible :customer_name
end

...带有嵌入式“联系人”...

class Contact
    include Mongoid::Document
    field :first_name, type: String

    attr_accessible :first_name

    embedded_in :customer
end

在我的控制器中,我得到了客户 (pk) 的 ._ids,以及要更新的特定嵌入式文档 (contact_pk):

Customer.update(
                 { 
                   "_id" => Moped::BSON::ObjectId(pk),"contacts._id" => Moped::BSON::ObjectId(contact_pk)
                 },
                 {
                   $set => {"contacts.$.first_name" => "Bob" }
                 }
                ) 
4

1 回答 1

0

update类方法实际上是伪装的Customer.with_default_scope.update,这意味着它update实际上是update来自的方法Mongoid::Criteria看起来像这样

# Update the first matching document atomically.
#
# @example Update the first matching document.
#   context.update({ "$set" => { name: "Smiths" }})
#
# @param [ Hash ] attributes The new attributes for the document.
#
# @return [ nil, false ] False if no attributes were provided.
#
# @since 3.0.0
def update(attributes = nil)
  update_documents(attributes)
end

注意它只需要一个attributes参数?这解释了错误消息。大概您期望update以与在 MongoDB shell 或 JavaScript 接口中相同的方式工作。

首先,您需要找到感兴趣的文档,然后调用update它:

Customer.where('_id' => Moped::BSON::ObjectId(pk), 'contacts._id' => Moped::BSON::ObjectId(contact_pk))
        .update($set => { 'contacts.$.first_name' => 'Bob' })
于 2014-03-19T04:40:40.920 回答