2016-03-31 11 views
13

私はMongoidをRailsプロジェクト(どちらも4.0.x)で使用しています。スキーマレスのデータを格納するハッシュフィールドを持つドキュメントがあります。この設定でmongoidハッシュフィールドの値を設定する

class Thing 
    field :name, type: String 
    field :mass, type: Integer 
    field :info, type: Hash 
end 

、私はそうのようなキー:endDateを持っている、と言う、物事を照会することができます

Thing.where("info.endDate"=>{'$exists'=>true}) 

そして、それはすべて素晴らしく、便利です。この:infoフィールドのハッシュフィールドを使用するのは、私が保存したいものが固定されたスキーマを持たず、あるものから別のものに変わるので、いいです。

でも、:infoハッシュの$setのキーと値のペアと同じドット構文を使用することはできません。 [1]

thing.set("info.endDate"=>Time.now) 

Raises a Mongoid::Errors::UnknownAttributeエラーが発生しました。

これは私のモデルにMongoid::Attributes::Dynamicを含める必要があることを示していますが、それはが私にはわかりますです。 The point of the hash field typeは、固定スキーマを持たないデータを扱うことができるようです。私はハッシュフィールドを使うために特別な "動的属性"モジュールを含める必要があるようには思えません。

だから、今、私はそうのように、定期的に古い[]構文を使用して値を更新した後、モデルにsaveを呼んでいる:

thing.info[:endDate] = Time.now 
thing.save 

しかし、それはよりよいだろうということが起こる多くの時間その値をちょうど$setにします。ハッシュフィールドの値を設定するための他の構文はありますか?私は上記のエラーメッセージと動的な属性が間違っている間違っている間違っていますか?私は今、ハッシュフィールドの2つのステップの更新をしていますか?

[1]確かに、私は最近mongomapperから移行しました。この構文の私の期待は、これまでmongomapperでこれを行うことができたことによって部分的に設定されています。

+1

私は –

+2

Iドン(このアプローチをテストしたことはありません)属性:: ::ダイナミックをMongoidとして定義されますembeds_oneは、あなたのために働くだろうと思います埋め込み文書が必要です。ハッシュフィールドが必要なのは、そこに格納されているデータがドキュメントごとに異なるからです。そして、mongoidは、そのハッシュ内の特定のキー/値のペアを照会する方法を私に与えます。私は$ setを使って、そのハッシュのキーと値のペアを簡単に更新できるようにしたいと考えています。 – Bee

+0

それは '.set(:info => {:endDate => Time.now})'ではありません '私はMongoDBと一緒に作業して以来、しばらくしてきました。 –

答えて

9

あなたが好きなハッシュフィールドを持つ事は、それははるかなどの動的なことができている動作します。したがって、コード内のバグによって意図しないフィールドを含むDBスキーマが汚染されないように、この機能はデフォルトでは無効になっています。

いいえ、ハッシュに2段階の更新を使用しても問題はありません。

[]、[] =はread_attribute()write_attribute()のショートカットで、Mongoid::Attributes::Dynamicを含まない場合に使用してください。動的属性を有効にしないで$setを使用しようとすると、定義された属性として動的属性が表示されないため、メソッドなしエラーが発生します。

ソースがMongoid::Attributes::Dynamicの場合は、動的属性機能を追加する必要があります。あなたは簡単にこれをスキップして、私は願ってい

2段階法による値の更新を行うことができます必要がある場合はそれ以外の場合は

thing = Thing.first 
thing.set("info.endDate" => Time.now) 
thing.reload # This will update the current variable 

は、以下の手順を実行する必要が Mongoid::Attributes::Dynamic含めて値を更新するにはこれはあなたの質問を少し明るくします。

出典:

Rails mongoid dynamic fields - no method error

Dynamic attributes with Rails and Mongoid

+0

私はまだこの答えに不満です。動的フィールドに関するドキュメントは、ドキュメントにフィールドを動的に追加することを指しているようです。宣言されたハッシュフィールド内でキー/値のペアを設定するようなことは、ダイナミックフィールドについて話しているときに参照しているものではありません。任意のキーと値のペアを追加できないハッシュデータ型は何ですか?そして、実際には、明らかに$ setを使用しない、任意の値をハッシュに追加することができます。しかし、多分私はここでモンゴイドのデザインと議論しているだけかもしれません。知りません。 – Bee

+1

@Beeハッシュフィールドに必要なときだけ '$ set'を使うことができないのは、欲求不満のようです。私の答えで説明したように、値が動的になる可能性があり、コードにエラーがあると、意図しないフィールドにつながる可能性があるため、 '$ set'を使用する機能が無効になっています。しかし、[]、[] =を使用しているときは、あなたが使用している値はかなりわかります。これはちょうどそれが設計された方法です。しかし、Hashフィールドに '$ set'を有効にすることで、そのモジュールを組み込み、Mongoidにコード化したコードを確実に伝えることができます。著者の視点から考えると正しいと思われます。 –

+1

優秀!!完璧に動作します:D –

1

私は間違った方法でパラメータを渡すと思います。コンマ

と矢印記号を置き換えあなたはこれに変更することができ、それが

thing.set("info.endDate", Time.now) 
+0

ありがとう!しかし、これはMongoid 3.xセットの構文です。 Mongoid 4.xから始めて、彼らはフィールド/値のペアのハッシュを渡して、セットしました。 – Bee

+0

はい@Bee、実際に私は現在のプロジェクトでmongoid 3.xを使用しています。 yes mongoid 4.xは、引数をキーと値のペアとして取ります。あなたの返信をありがとう – Sukanta

関連する問題