我有一个Projection模型,用于验证属性的唯一性" ppr"。我不想要多个Projection记录,其中:week,:player_id,:ppr,AND:created_at year都是相同的。 这里的关键问题是我不知道如何针对 created_at year 进行此验证。我不介意,如果有多个记录,其中:ppr,:player_id和:week都是相同的,只要它们是针对不同的created_at年份。
例如:
这是一张投影记录。
#<Projection id: 44, ppr: 3.5, salary: 6600, week: 1, created_at: "2014-09-04 06:05:34", player_id: 44>
如果我想创建这个额外的投影记录,即使created_at年是2015年而不是2014年,我当前的验证也不会允许它。
#<Projection id: 89, ppr: 3.5, salary: 6600, week: 1, created_at: "2015-09-05 06:05:34", player_id: 44>
如何修改我的验证以解释此额外约束并允许来自不同年份的记录?
我基本上需要结合这两个验证:
validates_uniqueness_of :ppr, :scope => [:week, :player_id], :if => :nfl?
validates_uniqueness_of :ppr, conditions: { -> { where("created_at >= ? and created_at <= ?", "#{Date.today.year}0101", "#{Date.today.year}1231") } }
以下是我目前的模型设置:
class Projection < ActiveRecord::Base
attr_accessible :ppr, :salary, :score, :week, :player_id, :created_at
belongs_to :player
validates_uniqueness_of :ppr, :scope => [:week, :player_id], :if => :nfl?
scope :for_year, lambda {|year| where("created_at >= ? and created_at <= ?", "#{year}0101", "#{year}1231")}
end
更新
由于显而易见的原因,这种语法不起作用,但我可以做类似的事情吗?
validates_uniqueness_of :ppr, :scope, :created_at => [:week, :player_id, created_at <= ?", "#{Date.today.year}0101", "#{Date.today.year}1231"], :if => :nfl?
答案 0 :(得分:1)
我建议编写一个查询此类记录存在的验证方法。由于数据每年是唯一的,因此查询当前年份的日期范围。
注意:这确实假设所有数据条目都是当前年份,因为您的条件与created_at属性相关联。如果您需要不同的时间段,请修改range
变量。
class Projection < ActiveRecord::Base
belongs_to :player
delegate :nfl?, to: :player
validates :player, presence: true
validate :unique_player_projection, if: :nfl?
private
def unique_player_projection
range = Time.now.beginning_of_year..Time.now.end_of_year
return unless Projection.exists?(player_id: player_id, ppr: ppr, week: week, created_at: range)
errors.add(:base, 'Projection not unique.')
end
end
此示例与数据库无关。如果您正在处理大量记录集,则会有更多优化的SQL查询。
我包含了nfl?
属性的委托。