2011-08-22 60 views
4

我想更新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 
=> true 

a.hash_field 
=> {:a => [1,2]} 

但是當我查詢作爲

A.last.hash_field 
=> {:a => [1]} 

由於實際上意味着它沒有更新任何 現在我怎麼會更新根據需要?

先謝謝了!

回答

2

這與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 

其次,在你Model(包括Mongoid::Document),使用新的類型,像這樣:

field :my_hash_field, :type => CompressedObject 

現在,你可以做任何你想要與現場每一次都將被序列化正確。

1

我的問題有點不同,但您可能從我的解決方案中獲益。 我有哈希映射字段的數組在我蒙戈文獻,這是最終處理了它的形式如下:

<% @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個鍵的每個(「索引」和「名」)映射在我的數組。 這是什麼我的文檔定義看起來像:

class Import::FileImportConfiguration 
    field :file_name, type: String 
    field :model, type: String 
    field :fieldz, type: Array, default: [] 
end