【问题标题】:How to validate uniqueness with scope?如何使用范围验证唯一性?
【发布时间】:2013-05-16 14:56:19
【问题描述】:

我有:

class Foo
  include Mongoid::Document

  field :year, :type => Integer, :default => Time.now.utc.year
  field :month, :type => Integer, :default => Time.now.utc.month
  field :day, :type => Integer, :default => Time.now.utc.day

  validates :day, :uniqueness => { :scope => [:month,:year] }
end

我做了以下两次:

Foo.create(:day => 24, :year => 2013, :month => 5)

我没有收到验证错误。相反,我有两条相同的记录。我做错了什么?

【问题讨论】:

  • 这两个创建执行的速度有多快,如果它们被立即触发,这里就有一个继承竞争条件。也许初始写入在第二次创建验证之前被缓存。我的建议是直接在 mongodb 中设置一个多键唯一约束。 db.foos.ensureIndex( { "day": 1, "year": 1, "month": 1 }, { unique: true } )
  • 不是马上。我可以等待 30 秒甚至几分钟,我仍然会得到重复的记录。任何地方都没有比赛条件。作为最后的手段,我可​​以直接在 Mongodb 中考虑唯一约束。但是,我希望通过 Mongoid(应用层)找到一种方法。
  • 在生产中你应该两者都做,如果遇到多个并发插入,可能会遇到上述竞争条件。至于手头的问题,我认为语法或逻辑上没有任何错误。可能的问题:Mongoid behaves slightly different to Active Record when using #valid? on already persisted data. Active Record's #valid? will run all validations whereas Mongoid's #valid? will only run validations on documents that are in memory as an optimization.mongoid.org/en/mongoid/docs/validation.html
  • 对于这种情况,插入在单个线程上运行(通过工作者/cron 作业)。不是同时的。怀疑这里会发生竞争条件
  • 来自mongoid.org/en/mongoid/docs/validation.html,对于 validates_uniqueness_of :name ... validates :name, uniqueness: true ... 验证属性是否唯一。请注意,对于嵌入式文档,这只会检查该字段在父文档的上下文中是否唯一,而不是在整个数据库中。

标签: mongodb mongoid


【解决方案1】:

试试

validates_uniqueness_of :day, scope: [:month,:year]

【讨论】:

    猜你喜欢
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 2023-03-07
    相关资源
    最近更新 更多