Могу ли я удалить встроенный документ в Mongoid без сохранения?


Определенно относится к этому вопросу, но поскольку четкого ответа не было, я чувствую, что должен спросить снова. Существует ли какой-либо способ удалить вложенный документ из монголоидного отношения embeds_many без сохранения?

Я хочу изменить массив встроенных документов в памяти, а затем сохранить все изменения с помощью одной операции обновления. В частности, я хотел бы:

  1. изменение массивов встроенных документов (добавление встроенного документа / удаление встроенного документа / edit embedded doc / etc).
  2. возможно, внести другие изменения в TLD.
  3. сохраняйте все изменения с помощью одного вызова базы данных.
3 4

3 ответа:

Можно удалить встроенный документ с помощью Mongoid без сохранения. Хитрость заключается в том, чтобы внести изменения из родительского объекта с помощью assign_attributes. Например:

class MyParent
  include Mongoid::Document

  field :name, type: String
  embeds_many :my_children

  def remove_my_child(child)
    assign_attributes(my_children: my_children.select { |c| c != child })
  end
end

class MyChild
  include Mongoid::Document

  embedded_in :my_parent

  def remove
    parent.remove_my_child(self)
  end
end

my_parent = MyParent.first
my_first_child = my_parent.my_children.first

# no mongo queries are executed
my_first_child.remove

# now we can make another change with no query executed
my_parent.name = 'foo'

# and finally we can save the whole thing in one query which is the
# reason we used an embedded document in the first place, right?
my_parent.save!

После еще двух лет использования Mongoid, я узнал, что нет никакого оператора для того, что я пытался достичь. Удаление встроенного документа с помощью Mongoid всегда приводит к вызову базы данных.

В ситуациях, подобных этой, проще обойти Mongoid и использовать mongo-ruby-driver напрямую.

Попробуйте mongoid'S

update_all()

Документация

Пример: Если бы я хотел сделать всех моих пользователей Джо

User.update_all(name: 'Joe')

Будет вести себя именно так, как вы ожидаете.