I'm getting a weird behaviour from Mongoid 4.0.0 and Rails 4, I have a 1-N relationship and I get a duplicate key error index when I try to save the N side of the relationship. Let me show you some code:
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
And here is the test that fails:
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
Executing this test yields the following:
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') }"
I've added a puts
command after the creation of the collection to verify that indeed, its ID is the same that is being duplicated. Furthermore, removing the statement pur.collection_id = col.id
results in the following error: NoMethodError: undefined method 'insert' for nil:NilClass
which leads me to believe that when I try to save the Purchase object, Mongoid automatically tries to insert the other side of the 1-N relationship, although it is already persisted.
Note that changing pur.collection_id = col.id
to pur.collection = col
changes nothing.
I can solve this by changing Collection.create
to Collection.new
but this is not a viable solution, as you might imagine, I need to be able to create Purchases of already existing Collections.
Why is this happening? I've looked in the documentation and there is no mention of this behaviour, which in my opinion makes no sense (or maybe I've been looking at this screen for too long).
Any idea how to solve this?
So I've finally figured it out, renaming the model Collection
to something else solved the problem, seems like Mongoid doesn't like that name for models, even in an isolated namespace engine.