0

記号をキーとして使用するハッシュをMongoに提供してドキュメントを保存すると、Mongoはそれを「文字列化」します。つまり、キーは文字列に変換されます。要約する:

条件:ハッシュキーは次のようになります:
---------- ------------------
ドキュメントの記号または文字列を初期化した後
ドキュメント文字列を保存した後
ドキュメント文字列をフェッチした後

この「非対称性」は、私のテストにいくつかの醜さをもたらしました。キーが常に文字列であることに「依存」できるようにしたいのですが、ドキュメントが初期化されたばかりかどうかについて心配する必要はありません。

これを回避するための1つ以上のエレガントな方法は何ですか?

注:私の場合、Mongoidを使用していますが、この質問が必ずしもMongoid固有であるとは限りません。おそらく、MongoDBを使用するすべてのRailsプロジェクトに適用されます。

4

2 に答える 2

1

私の現在の解決策は、を呼び出すために各フィールドセッターをオーバーライドすることstringify_keys!です。例えば:

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

これは私がこれまでに見つけた中で最高です。私は他の選択肢を検討しました:

  • before_validationコールバックを使用します。しかし、私はこのアプローチが好きではありません。valid?文字列化をトリガーするために電話をかける必要はありませんでした。

  • を使用しafter_initializeます。ただし、これは初期化後にセッターを呼び出す場合には対応していません。

于 2012-06-25T20:01:54.493 に答える
1

これらの線に沿った何かが機能する可能性があります。基本的に、このコードはMongoidのfieldマクロ(そのセッター)を再定義します。

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}

これは最もクリーンな実装ではないかもしれませんが、あなたはその考えを理解します。

于 2012-06-25T20:23:00.403 に答える