【问题标题】:Rails: Validates uniqueness of scoped by dateRails:按日期验证范围的唯一性
【发布时间】:2009-09-30 16:53:20
【问题描述】:

我有一个 Rails 模型,应该只允许每个用户每天保存/更新一次模型。我有一个回调来按用户和日期进行查找,然后添加到错误中,但这很丑陋并且感觉不像轨道。我有典型的 created_at / updated_at 列(时间部分很重要/我需要保留它)。

所以我想我可以:

1)创建另一个模型属性,它只是创建日期和范围(bleh)

2) 使用 :scope 属性,但以某种方式只获取 created_at 的日期部分,例如validates_uniqueness_of :user, :scope => :created_at.to_date (显然不起作用)

3) 验证除非 => Proc.new{ |o|与我现有回调匹配的 Finder }(粗略)

http://ar.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M000086

这些不会太多,但我宁愿用 SQL 而不是 Ruby 完成(出于明显的可扩展性原因)。

有什么想法吗?有没有更好的办法?

【问题讨论】:

    标签: ruby-on-rails ruby scope validates-uniqueness-of


    【解决方案1】:

    我最终将conditions 选项与validates_uniqueness_of 一起使用,并将其传递给将检查的记录限制为今天的记录。

    class AttendanceRecord < ActiveRecord::Base
      validates_uniqueness_of :user_id, conditions: { -> { where("DATE(created_at) = ?", Date.today) } }
    end
    

    【讨论】:

    • 不认为你需要额外的大括号围绕条件(但网站条件也不会让我编辑它)
    • 如果日期被硬编码为Date.today,则此方法有效,但如果created_at 日期(或其他模型的等效属性)设置为今天以外的其他值,则允许多个重复的出席记录.
    • 记住还要添加一个唯一索引以在数据库级别强制执行此规则。这在 Rails 文档中提到了唯一性验证:guides.rubyonrails.org/…
    【解决方案2】:

    您也可以编写自己的验证方法。这完全是easy。并且在自定义验证方法中,date_trunc (Postgresql) 可用于查找所需时间跨度内的现有记录。 date_trunc 也可以参数化(例如小时、天、周、月)。

    可以使用一个简单的条件代替 date_trunc 来查找冲突记录。例如 ["user_id = ? AND updated_at >= ?", self.user_id, Time.now.beginning_of_day] 而且我猜这个记录查找应该更快,因为它可以使用索引。

    【讨论】:

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