尝试保存先前已销毁的Mongoid对象时出现奇怪的行为。鉴于此类定义:
class Foo
include Mongoid::Document
end
保存实例后删除它,我无法再次保存:
Foo.count # => 0
f = Foo.create # => #<Foo _id: 522744a78d46b9b09f000001, >
Foo.count # => 1
f.destroy # => true
Foo.count # => 0
f.save # => true
# it lied - didn't actually save:
Foo.count # => 0
# these may be relevant:
f.persisted? # => false
f.destroyed? # => true
f.new_record? # => false
f.changed? # => false
这是一个我希望通过的失败的RSpec测试:
describe Foo do
it 'should allow saving a Foo instance after destroying it' do
expect(Foo.count).to eq(0)
f = Foo.create
expect(Foo.count).to eq(1)
Foo.all.destroy
expect(Foo.count).to eq(0)
f.save # => true
expect(Foo.count).to eq(1) # error - returns 0
end
end
这是预期的行为吗?我的用例实际上是使用单例对象(虽然提到它但不想让问题更复杂); Foo.instance
返回被Foo.all.destroy
销毁的同一个对象,这会破坏事物。
答案 0 :(得分:2)
<强>型号#保存
以原子方式将更改的属性保存到数据库,或者如果是新文件,则插入文档。会引发验证错误。
销毁后,文档不是新文档,并且没有更改的属性,因此save
只返回没有错误。从严格意义上说,这似乎是预期的行为。
您可以使用Model#upsert
:
在文档上执行MongoDB
upsert
。如果文档存在于数据库中,它将被内存中文档的当前属性覆盖。如果数据库中不存在该文档,则会插入该文档。
这实际上会使用相同的ID保存文档,但它仍然是frozen?
并标记为destroyed?
。因此,根据评论中的疯狂-36的建议,仅仅clone
文档可能会更好。