0

Mongoid 4.0.0 と Rails 4 から奇妙な動作が発生しています。1 対 N の関係があり、関係の N 側を保存しようとすると、重複キー エラー インデックスが発生します。いくつかのコードをお見せしましょう:

module MyEngine
  class Collection
    include Mongoid::Document
    include Mongoid::Timestamps

    field :name, type: String
    field :price, type: Integer, default: 0

    has_many :purchases, class_name: 'MyEngine::Purchase'

    validates_presence_of :name
  end
end

module MyEngine
  class Purchase
    include Mongoid::Document
    include Mongoid::Timestamps

    field :paid, type: Integer, default: 0

    belongs_to :collection, class_name: 'MyEngine::Collection'
  end
end

そして、失敗するテストは次のとおりです。

    test "should save purchase" do
      col = Collection.create(name:'test')
      pur = Purchase.new
      pur.collection_id = col.id
      assert pur.save, "Could not save purchase"
    end

このテストを実行すると、次の結果が得られます。

Moped::Errors::OperationFailure: The operation: #<Moped::Protocol::Command
  @length=74
  @request_id=7
  @response_to=0
  @op_code=2004
  @flags=[]
  @full_collection_name="dummy_test.$cmd"
  @skip=0
  @limit=-1
  @selector={:getlasterror=>1, :w=>1}
  @fields=nil>
failed with error 11000: "insertDocument :: caused by :: 11000 E11000 duplicate key error index: dummy_test.loot_collections.$_id_  dup key: { : ObjectId('54c3057350686f51a8000000') }"

コレクションの作成後にコマンドを追加してputs、実際にその ID が複製されているものと同じであることを確認しました。さらに、ステートメントを削除するpur.collection_id = col.idと、次のエラーが発生します。NoMethodError: undefined method 'insert' for nil:NilClassこれにより、Purchase オブジェクトを保存しようとすると、Mongoid は 1-N 関係の反対側を自動的に挿入しようとしますが、それは既に永続化されています。

pur.collection_id = col.idに変更しても何も変わらないことに注意してくださいpur.collection = col

に変更することCollection.createでこれを解決できますCollection.newが、これは実行可能な解決策ではありません。ご想像のとおり、既存のコレクションの購入を作成できるようにする必要があります。

なぜこうなった?私はドキュメントを調べましたが、この動作については言及されていません。これは私の意見では意味がありません (または、この画面を長時間見すぎている可能性があります)。

これを解決する方法はありますか?

4

1 に答える 1