我想在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
=> true
a.hash_field
=> {:a => [1,2]}
但是当我查询为
时A.last.hash_field
=> {:a => [1]}
谢谢意味着它实际上没有更新任何东西 现在我如何根据需要更新?
提前致谢!
答案 0 :(得分:3)
这可能与Mongoid浅拷贝哈希的方式有关。如果是这样,那么这可能会有助http://spin.atomicobject.com/2011/04/13/mongoid-hash-field-types-watch-out/
注意:我没有根据您的具体情况测试解决方案
答案 1 :(得分:2)
这与Mongoid如何优化字段更新有关。具体来说,由于您正在更新哈希字段内的元素,因此字段“观察者”不会获取内部更新,因为字段自身的值(指向哈希)保持不变。
我采用的解决方案是为我想存储的任何复杂对象(例如Hash)提供通用序列化器。这是一个好处,它是一个通用的解决方案,只是工作。缺点是它会阻止您使用内置的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
其次,在Model
(包括Mongoid::Document
)中,使用新类型,如下所示:
field :my_hash_field, :type => CompressedObject
现在,您可以使用该字段执行任何操作,并且每次都可以正确序列化。
答案 2 :(得分:1)
我的问题有点不同,但你可能会从我解决它的方式中受益。 我的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 %>
我在我的数组中存储了每个2个键(“index”和“name”)的映射。 这就是我的文档定义:
class Import::FileImportConfiguration
field :file_name, type: String
field :model, type: String
field :fieldz, type: Array, default: []
end