Mongoid / Moped обновляет внедренный документ - ArgumentError - неверное количество аргументов (2 для 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
И в моем контроллере я получаю._ids как клиента (pk), так и конкретный внедренный документ для обновления (contact_pk):
Customer.update(
{
"_id" => Moped::BSON::ObjectId(pk),"contacts._id" => Moped::BSON::ObjectId(contact_pk)
},
{
$set => {"contacts.$.first_name" => "Bob" }
}
)
1 ответ
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 или в интерфейсе JavaScript.
Сначала вам нужно найти интересующий вас документ, а затем позвонить update
на что:
Customer.where('_id' => Moped::BSON::ObjectId(pk), 'contacts._id' => Moped::BSON::ObjectId(contact_pk))
.update($set => { 'contacts.$.first_name' => 'Bob' })