Двойная ассоциация картографирования монго для манипуляций в памяти - PullRequest
0 голосов
/ 09 марта 2012

Я бы хотел 1. Извлечь объект 1 и объект 2 из базы данных (у каждого по 2 ассоциации has_many каждый) 2. Создать объект 3, который является клоном объекта 1 и, следовательно, еще не имеет ассоциаций 2. Дублировать объект 2ассоциации и добавьте их к ассоциациям объекта 3. 3. Используйте новый объект 3 для операций в памяти 4. Выйдите из процесса без постоянного изменения базы данных - объект 1 и объект 2 все еще имеют свои первоначальные ассоциации, когда процесс завершается

Что вместо этого происходит

  1. Я беру объект 1 и объект 2 из базы данных (оба имеют по 2 ассоциации has_many каждый)
  2. Я создаю объект 3, который является клоном объекта1 и, следовательно, еще не имеет ассоциаций
  3. Я дублирую ассоциации объекта 2 и добавляю их к ассоциациям объекта 3
  4. Я использую новый объект 3 для операций в памяти
  5. Я выхожу изпроцесс ОДНАКО теперь есть постоянное изменение в базе данных - объект 2 больше не имеет своих ассоциаций, потому чтоSE их ключи были изменены на (Временный) объект 3 id.

Вот мой код.Обратите внимание, что все содержат массив с произвольным числом объектов в нем

object1 = all.last.clone #we take the most recently created object
all.each do |instance|
  instance_association1 = (instance.association1).dup
  object1.association1 += instance_association1 #BUG this moves the association
  object1.association1.uniq!
  instance_association2 = (instance.association2).dup
  object1.association2 += instance_association2
  object1.association2.uniq!
end

Обратите внимание, что теперь, когда я говорю: all.last.association1, я получаю пустой массив.

Помогите!!

1 Ответ

1 голос
/ 12 марта 2012

Ассоциации MongoMapper могут быть немного переусердствовали с экономией.Я хочу пересмотреть его когда-нибудь, но это не простая проблема.

Код, который сообщит вам, когда произойдет сохранение, - many_documents_proxy.rb .Когда вы делаете my_association = [...], replace - это метод, который вызывается.

Единственный метод, который не делает сохранения, - это build, так что вы можете создать свой временный объект следующим образом.:

tmp = all.last.clone
all.each do |instance|
  instance.association1.each { |doc| tmp.association1.build(doc.attributes) }
  tmp.association1.uniq!
  # ...
end

В общем, вы можете конвертировать все связанные документы в массивы и не беспокоиться о сохранении ...

associations1 = []
associations2 = []
all.each do |doc|
  associations1 += doc.associations1.to_a
  associations2 += doc.associations2.to_a
end
assocations1.uniq!
assocations2.uniq!

ОДНАКО, берегитесь!Метод Ruby uniq выглядит так, как будто он использует метод Ruby #hash для вычисления равенства, что может не дать вам желаемых результатов в этом случае.Сделайте несколько тестов, чтобы убедиться, что my_obj.hash == my_obj2.hash, если my_obj == my_obj2.См. в этом обсуждении для стратегий по реализации вашего собственного метода #hash, если вам нужен этот путь.

...