我有以下课程:
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)
哪个有效,但有人可以解释为什么我的第一种方法不起作用,以及我的第二种方法是通过Mongoid更新文档的常用方法吗?
答案 0 :(得分:2)
问题在我的机器上重现,我找到了解决方案。
根据{{3}}或document,如果发生验证错误, Model#create!
会引发错误,而不是数据库错误 。所以这不是你问题的解决方案。
the code on github with(safe: true)
可以告诉Mongoid引发Runtime Persistence Option中定义的数据库错误。在你的情况下。错误如下:
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中设置为默认值,如the driver Moped中所述。
也许您希望找到一个Magazine.find("Yolo")
的杂志来默认使用MongoDB创建的_id
索引。即使_id
与name
相同,但Mongoid也不够聪明,无法使用_id
来查找文档。
答案 1 :(得分:1)
我想我有点惊讶你的第二次创造!不会引发错误。
尝试使用与update相结合的find方法,这是用于更新属性的非常常见的单行程序:
Magazine.find('Yolo').update_attributes(count: 42)