0

私は次のクラスを持っています:

class Magazine
  include Mongoid::Document

  field :name
  field :count
  field :_id, default: -> { name }

を通じて、このタイプの新しいドキュメントを作成しますMagazine.create!(name: "Yolo", count: 2)。これはうまくいきます。今、MongoDB でこのドキュメントを更新したい場合、カウントが変更されたので、これでうまくいくと思いました:

Magazine.create!(name: "Yolo", count: 42)

名前は同じ識別子にマップされるため、ドキュメントはオーバーライドされます。操作は成功したように見えますが、MongoDB ではドキュメントが更新されませんでした。

代わりに、私はしなければなりません:

Magazine.where(name: "Yolo").first.update_attributes!(count: 42)

どちらが機能しますが、最初のアプローチが機能しない理由と、2 番目のアプローチが Mongoid を介してドキュメントを更新する一般的な方法である場合、誰かが説明できますか?

4

2 に答える 2

2

問題は私のマシンで再現され、解決策が見つかりました。

Model#create!ドキュメントまたはgithub のコードに従って、データベース エラーではなく、検証エラーが発生した場合にエラーを発生させます。したがって、それはあなたの質問に対する解決策ではありません。

Runtime Persistence Option、ドライバー Mopedwith(safe: true)で定義されたデータベース エラーを発生させるように Mongoid に指示できます。あなたの場合。エラーは次のようになります。

1.9.3-p0 :009 > Magazine.with(safe: true).create!(name: "Yolo", count: 42)
Moped::Errors::OperationFailure: The operation: #<Moped::Protocol::Command
  @length=71
  @request_id=7
  @response_to=0
  @op_code=2004
  @flags=[]
  @full_collection_name="mongoid.$cmd"
  @skip=0
  @limit=-1
  @selector={:getlasterror=>1, :safe=>true}
  @fields=nil>
failed with error 11000: "E11000 duplicate key error index: mongoid.magazines.$_id_  dup key: { : \"Yolo\" }"

さらに、ドキュメントで説明されているように、構成 YAML でセーフ モードをデフォルトとして設定できます。

おそらく、デフォルトで MongoDB によって作成されMagazine.find("Yolo")た のインデックスを使用する雑誌を見つけたいと思うでしょう。が と同じであった_idとしても、Mongoid は文書を見つけるのに十分賢くありません。_idname_id

于 2013-09-20T17:27:13.287 に答える