具有嵌入关联的深层克隆文档

Yeg*_*eps 6 mongodb mongoid

您将如何在MongoDB中深入克隆文档(mongoid)

我尝试过这样的事情;

original = Car.find(old_id)
@car = original.clone
@car._id = BSON::ObjectId.new
Run Code Online (Sandbox Code Playgroud)

但是我之后遇到问题的反序列化问题.

如何使用除_id之外的所有文档属性进行深度克隆?

编辑:在遵循Zachary的示例后,我遇到了一些针对重复文档的自定义序列化类的问题.

class OptionHash
  include Mongoid::Fields::Serializable

  # Convert the keys from Strings to Symbols
  def deserialize(object)
    object.symbolize_keys!
  end

  # Convert values into Booleans
  def serialize(object)
    object.each do |key, value|
    object[key] = Boolean::MAPPINGS[value]
  end
end
Run Code Online (Sandbox Code Playgroud)

对于重复文档,对象为零.Car.find(old_id).attributes确实不包含自定义序列化的字段,为什么会这样,我该如何包含它?

Zac*_*ker 7

你不需要在这上面调用.clone,你可以使用原始数据attributes.例如,如果找到一个,则下面的方法/示例将在整个文档中给出新的ID.

def reset_ids(attributes)
    attributes.each do |key, value|
        if key == "_id" and value.is_a?(BSON::ObjectId)
            attributes[key] = BSON::ObjectId.new
        elsif value.is_a?(Hash) or value.is_a?(Array)
            attributes[key] = reset_ids(value)
        end        
    end
    attributes
end


original = Car.find(old_id)
car_copy = Car.new(reset_ids(original.attributes))
Run Code Online (Sandbox Code Playgroud)

你现在有一份汽车的副本.这是低效的,因为它必须通过记录的整个哈希来确定嵌入文档中是否存在任何嵌入文档.如果您知道它的结构,您最好自己重置结构,例如,如果您将部件嵌入汽车,那么您可以这样做:

original = Car.find(old_id)
car_copy = Car.new(original.attributes)
car_copy._id = BSON::ObjectId.new
car_copy.parts.each {|p| p._id = BSON::ObjectId.new}
Run Code Online (Sandbox Code Playgroud)

这比仅进行通用重置更有效.