Ruby on rails 3 更新Mongoid中的哈希类型属性
我想更新Mongoid中的哈希类型属性 这里有一个例子Ruby on rails 3 更新Mongoid中的哈希类型属性,ruby-on-rails-3,mongoid,Ruby On Rails 3,Mongoid,我想更新Mongoid中的哈希类型属性 这里有一个例子 class A include Mongoid::Document field :hash_field, :type => Hash end 现在让我们假设已经有了填充数据,比如 A.last.hash_field => {:a => [1]} 现在我想更新散列,并希望最终输出为{:a=>[1,2]} 我试着 a = A.last a.hash_field[:a] << 2 a.save =>
class A
include Mongoid::Document
field :hash_field, :type => Hash
end
现在让我们假设已经有了填充数据,比如
A.last.hash_field
=> {:a => [1]}
现在我想更新散列,并希望最终输出为{:a=>[1,2]}
我试着
a = A.last
a.hash_field[:a] << 2
a.save
=> true
a.hash_field
=> {:a => [1,2]}
谢谢,意思是实际上它没有更新任何东西
现在我怎样才能根据需要进行更新
提前谢谢 这可能与Mongoid浅拷贝散列的方式有关。如果是这样,那么这可能会有所帮助
注意:我没有针对您的特定情况测试解决方案这与Mongoid如何优化字段更新有关。具体地说,由于您正在更新散列字段中的元素,字段“watcher”不会在中拾取更新,因为字段自身的值(指向散列)保持不变 我采用的解决方案是为我想要存储的任何复杂对象(例如哈希)提供一个通用序列化程序。这样做的好处是,它是一个通用的解决方案,可以正常工作。缺点是,它会阻止您使用内置的Mongo操作查询哈希的内部字段,并且还会占用一些额外的处理时间 没有进一步的告别,这里是解决方案。 首先,为新的Mongoid自定义类型添加此定义
class CompressedObject
include Mongoid::Fields::Serializable
def deserialize(serialized_object)
return unless serialized_object
decompressed_string = Zlib::Inflate.inflate(serialized_object.to_s)
Marshal.load(decompressed_string)
end
def serialize(object)
return unless object
obj_string = Marshal.dump(object)
compressed_string = Zlib::Deflate.deflate(obj_string, Zlib::BEST_SPEED)
BSON::Binary.new(compressed_string)
end
end
其次,在您的模型中(包括Mongoid::Document
),使用如下新类型:
field :my_hash_field, :type => CompressedObject
现在,您可以对该字段执行任何操作,每次都将正确序列化。我的问题有点不同,但您可能会从我解决该问题的方式中受益。
我在mongo文档中有一个哈希映射字段数组,这是最终处理它的表单:
<% @import_file_import_configuration.fieldz.each do |fld| %>
<tr>
<td>
<input type="number" name="import_file_import_configuration[fieldz][][index]" value='<%=fld["index"]%>'/>
</td><td>
<input type="textbox" name="import_file_import_configuration[fieldz][][name]" value='<%=fld["name"]%>'/>
</td>
</tr>
<% end %>
添加deep_拷贝和显式调用帮助了我。谢谢
<% @import_file_import_configuration.fieldz.each do |fld| %>
<tr>
<td>
<input type="number" name="import_file_import_configuration[fieldz][][index]" value='<%=fld["index"]%>'/>
</td><td>
<input type="textbox" name="import_file_import_configuration[fieldz][][name]" value='<%=fld["name"]%>'/>
</td>
</tr>
<% end %>
class Import::FileImportConfiguration
field :file_name, type: String
field :model, type: String
field :fieldz, type: Array, default: []
end