如何在mongoid中强制执行独特的嵌入式文档

ops*_*psb 9 ruby-on-rails mongodb mongoid ruby-on-rails-3

我有以下型号

class Person 
  include Mongoid::Document
  embeds_many :tasks
end

class Task
  include Mongoid::Document
  embedded_in :commit, :inverse_of => :tasks
  field :name
end
Run Code Online (Sandbox Code Playgroud)

我如何确保以下内容?

person.tasks.create :name => "create facebook killer"
person.tasks.create :name => "create facebook killer"

person.tasks.count == 1

different_person.tasks.create :name => "create facebook killer"
person.tasks.count == 1
different_person.tasks.count == 1
Run Code Online (Sandbox Code Playgroud)

即任务名称在特定人员中是唯一的


检查了索引上的文档后,我认为以下内容可能有效:

class Person 
  include Mongoid::Document
  embeds_many :tasks

  index [
      ["tasks.name", Mongo::ASCENDING], 
      ["_id", Mongo::ASCENDING]
  ], :unique => true
end
Run Code Online (Sandbox Code Playgroud)

person.tasks.create :name => "create facebook killer"
person.tasks.create :name => "create facebook killer"
Run Code Online (Sandbox Code Playgroud)

仍然会产生重复.


上面显示在Person中的索引配置将转换为mongodb

db.things.ensureIndex({firstname : 1, 'tasks.name' : 1}, {unique : true})
Run Code Online (Sandbox Code Playgroud)

小智 5

您不能仅在任务上放置验证器吗?

validates :name, :uniqueness => true
Run Code Online (Sandbox Code Playgroud)

那应该确保父文档中的唯一性。

  • 实际上,嵌入式文档上的validates_uniqueness_of的作用域是父文档。 (7认同)

Gat*_* VP 1

默认情况下,索引不是唯一的。如果你查看Mongo 文档,就会发现唯一性是一个额外的标志。

我不知道确切的 Mongoid 翻译,但你正在寻找这样的东西:

db.things.ensureIndex({firstname : 1}, {unique : true, dropDups : true})