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)

哪个有效,但有人可以解释为什么我的第一种方法不起作用,如果我的第二种方法是通过 Mongoid 更新文档的常用方法?

4

2 回答 2

2

该问题在我的机器上重现,我找到了解决方案。

Model#create!根据github 上的文档或代码,如果发生验证错误,而不是数据库错误,则会引发错误。所以这不是你问题的解决方案。

运行时持久性选项 with(safe: true)可以告诉 Mongoid 引发在驱动程序 Moped中定义的数据库错误。在你的情况下。错误看起来像:

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即使_id与 同name,Mongoid 也不够聪明,无法_id用来查找文档。

于 2013-09-20T17:27:13.287 回答
1

我想我有点惊讶你的第二次创造!不会引发错误。

尝试将 find 方法与 update 结合使用,这是一种非常常见的更新属性的单行方法:

Magazine.find('Yolo').update_attributes(count: 42)
于 2013-09-20T15:05:31.227 回答