【问题标题】:How to check if value unique for a certain period如何检查某个时期的值是否唯一
【发布时间】:2014-01-20 20:01:32
【问题描述】:

我有一个带有 phone_id 属性的 Ratings 模型。在创建新的评级对象之前,我想检查 phone_id 在过去一周内是否唯一。

在我的模型中,我想在 before_save 回调中做这样的事情:

self.all(:conditions => {:created_at => (1.week.ago..Date.today)}).include? self.phone_id

【问题讨论】:

  • 所以您使用的是 Rails 2?究竟是什么版本?
  • 我正在使用 rails 3.2.12

标签: ruby-on-rails ruby-on-rails-3.2 rails-activerecord


【解决方案1】:

我会用干净的 sql 来做(性能)

select count(phone_id) from ratings where created_at < DATE_SUB(NOW(), INTERVAL 1 MONTH)

【讨论】:

    【解决方案2】:

    您可以使用带有约束的 ActiveRecord 验证。

    class Rating < ActiveRecord::Base
      validates_uniqueness_of :phone_id, conditions: -> { where(:created_at => (1.week.ago..Date.today)) }
    end
    

    【讨论】:

      【解决方案3】:

      您可以在创建时使用验证:

      class Rating < ActiveRecord::Base
        validate :unique_phone_within_last_week?, on: :create
      
      private
        def unique_phone_within_last_week?
          self.class.where("created_at > ?", 1.week.ago.to_date)
            .where(phone_id: phone_id).empty? ||
          errors.add(:phone_id, 'is not unique within last week') && false
        end
      end
      

      在 Rails 4 中,您可以将 validates_uniqueness_of 与条件 proc 一起使用:

      class Rating < ActiveRecord::Base
        validates_uniqueness_of :phone_id,
          conditions: -> { where('created_at > ?', 1.week.ago.to_date) }
      end
      

      阅读有关validates_uniqueness_of 的更多信息。

      检查 SQL 将是最佳的:

      SELECT COUNT(*) FROM "ratings"
      WHERE "ratings"."phone_id" = 2 AND ("created_at" > '2014-01-14');
      

      还要注意

      使用区间1.week.ago..Date.today 似乎是个坏主意, 因为今天(检查日)创建的记录超出了范围。

      '2014-01-21 09:10:21' BETWEEN '2014-01-14 11:23:30' AND '2014-01-21' 为假

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-29
        • 2022-01-21
        • 1970-01-01
        • 1970-01-01
        • 2016-11-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多