我在使用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" }
}
)
答案 0 :(得分:0)
update
类方法实际上是伪装Customer.with_default_scope.update
,这意味着update
实际上是来自update
和that looks like this的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' })