如何检查特定时期内的值是否唯一

时间:2014-01-20 20:01:33

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

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

在我的模型中,我想在before_save回调中执行类似的操作:

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

3 个答案:

答案 0 :(得分:0)

我会在干净的sql(性能)中做到这一点

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

您可以在create:

上使用验证
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'是假的