用Rails和Mongodb串行化键的优雅方法?

时间:2012-06-25 20:01:54

标签: ruby-on-rails ruby mongodb

如果您为Mongo提供使用符号作为键并保存文档的哈希,它将“字符串化”它,这意味着键将转换为字符串。总结一下:

condition:                       hash keys will be:
----------                       ------------------
after initializing a document    symbols or strings
after saving a document          strings
after fetching a document        strings

这种“不对称”在我的测试中导致了一些丑陋。我希望能够“依赖”键始终是字符串 - 而不用担心文档是否刚刚初始化。

避免这种情况的一种或多种优雅方法是什么?

注意:就我而言,我使用的是Mongoid,但我认为这个问题不一定是Mongoid特有的。它可能适用于任何使用MongoDB的Rails项目。

2 个答案:

答案 0 :(得分:1)

我目前的解决方案是覆盖每个字段设置器以调用stringify_keys!。例如:

def field_name=(x)
  x.stringify_keys! if x
  super(x)
end

这是迄今为止我发现的最好的。我考虑过其他选择:

  • 使用before_validation回调。但是,我不喜欢这种方法。我不想调用valid?来触发字符串化。

  • 使用after_initialize。但是,这不能处理初始化后调用setter的情况。

答案 1 :(得分:1)

这些方面的某些方面可行。基本上这段代码重新定义了Mongoid的field宏(它的setter)。

require 'mongoid'

module Stringifier
  def field name, args = {}
    super # call mongoid implementation

    define_method "#{name}=" do |val|
      val.stringify_keys! if val && val.respond_to?(:stringify_keys!)
      super(val)
    end
  end
end

class Foo
  include Mongoid::Document
  extend Stringifier

  field :subhash, type: Hash
end

f = Foo.new
f.subhash = {a: 1, b: 2}

puts f.subhash
# >> {"a"=>1, "b"=>2}

这可能不是最干净的实现,但你明白了。