Mongoid / Moped更新嵌入文档 - ArgumentError - 参数个数错误(2个为1)

时间:2014-03-19 04:00:36

标签: ruby mongodb sinatra mongoid moped

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

1 个答案:

答案 0 :(得分:0)

update类方法实际上是伪装Customer.with_default_scope.update,这意味着update实际上是来自updatethat looks like thisMongoid::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' })