用作哈希键的符号在序列化时会转换为字符串
当我将数组或哈希分配给 Mongo 文档的属性时,它会正确显示 当符号用作哈希键时,它们除外。简单示例:
irb>MyMongoModel.create :some_attr => {:a => [:b,:c]}
=> #<MyMongoModel _id: 4d861c34c865a1f06a000001, some_attr: {:a=>[:b, :c]}>
irb>MyMongoModel.last
=> #<MyMongoModel _id: 4d861c34c865a1f06a000001, some_attr: {"a"=>[:b, :c]}>
请注意 some_attr
被检索为 {"a"=>[:b, :c]}
,而不是 {:a=>[:b, :c]}
嵌套哈希也会发生这种情况(例如,在数组或其他哈希内部)。在这种情况下有没有办法保留符号?
解决方案
我在存储之前使用 YAML 手动序列化 some_attr
- YAML.dump(或 Object#to_yaml
),并在存储之后使用 YAML::load读取属性。 YAML 更好地保留序列化对象。 ActiveRecord 使用 YAML 在 ActiveRecord::Base
上实现其 serialize
类方法。
When I assign an Array or Hash to an attribute of a Mongo document, it gets properly
serialized except for Symbols when they are used as Hash keys. Simple example:
irb>MyMongoModel.create :some_attr => {:a => [:b,:c]}
=> #<MyMongoModel _id: 4d861c34c865a1f06a000001, some_attr: {:a=>[:b, :c]}>
irb>MyMongoModel.last
=> #<MyMongoModel _id: 4d861c34c865a1f06a000001, some_attr: {"a"=>[:b, :c]}>
Please, note that some_attr
is retrieved as {"a"=>[:b, :c]}
, not as{:a=>[:b, :c]}
This also happens for nested Hashes (e.g., inside of Arrays or other Hashes). Is there a way to preserve Symbols in such cases?
Solution
I'm using YAML to manually serialize some_attr
- YAML.dump (or Object#to_yaml
) before storing, and YAML::load after reading the attribute. YAML preserves the serialized object better. ActiveRecord is using YAML to implement its serialize
class method on ActiveRecord::Base
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这很可能与您用来为模型提供持久层的 ORM 有关。您可以使用一个方法包装
some_attr
,该方法以HashWithIn DifferentAccess
的形式返回它,然后您可以使用字符串或数组访问它。由于您使用的是 Rails,因此可以通过调用 Hash 对象上的with_in Different_access
方法来激活此功能。 (如果你有一个 Hash 对象数组,当然你需要对每个对象调用它)该方法将返回相同的哈希值,但符号查找将起作用。从您的代码:
希望这有帮助!
More than likely this has to do with the ORM you are using to provide the persistance layer for the model. You can probably wrap
some_attr
with a method that returns it in the form of aHashWithIndifferentAccess
which you can then access with either strings or arrays. Since you are using Rails, this functionality can be activated by calling thewith_indifferent_access
method on the Hash object. (If you have an array of Hash objects, you'll need to call it on each one of course) The method will return the same hash, but then symbol lookups will work.From your code:
Hope this helps!
这里的罪魁祸首是 BSON 序列化。当您序列化用作哈希键的符号时,它实际上会被转换为字符串,当您返回它时,您会得到字符串而不是符号。
我遇到了和你一样的问题,我正在考虑扩展 Hash 类以包含一种将所有“字符串”键转换为 :symbols 的方法。
不幸的是,我不在 Rails 上,所以我无法按照 ctcherry 的建议使用
with_in Different_access
。the culprit here is the BSON serialization. when you serialize a symbol used as a key for hashes, it is actually translated to a string and when you ask it back you get the string instead of the symbol.
i'm having the same problem as you and i'm thinking of extending the Hash class to include a method to convert all the "string" keys to :symbols.
unfortunately i'm not on Rails so i cannot use the
with_indifferent_access
as suggested by ctcherry.我不确定是否保留符号,但您可以将字符串转换回符号。
I'm not sure about preserving symbols but you can convert the strings back to symbols.
发现这个,效果很好,并且您已将该字段定义为哈希:
https://github.com/mindscratch /mongoid-indifferent-access
Found this, works well and you have define the field as Hash:
https://github.com/mindscratch/mongoid-indifferent-access