拥有属于某个类别的产品。想要在短时间内创建促销活动(比方说一两周),但在此期间每个类别只能促销一次。
如何为此创建自定义验证?
product class
belongs_to :categories
name:string
desc:text
reg_price:decimal
category_id:integer
promo_active:boolean
promo_price:decimal
promo_start:datetime
promo_end:datetime
end
category class
has_many :products
name:string
end
更新可能的解决方案???
class Product < ActiveRecord::Base
attr_accessible :name, :desc, :reg_price, :category_id, :promo_active, :promo_price, :promo_start, :promo_end
belongs_to :category
#validate :check_unique_promo
#Tweaked original to be more exact and
#Give clue if its the start or end date with the error.
validate :check_unique_promo_start
validate :check_unique_promo_end
def check_unique_promo
errors.add_to_base("Only 1 promo allowed") unless Product.count(:conditions => ["promo_active = ? AND promo_end < ?", true, self.promo_start]) == 0
end
def check_unique_promo_start
errors.add_to_base("Start date overlaps with another promotion.") unless self.promo_active == false || Product.count(:conditions => ['promo_end BETWEEN ? AND ? AND category_id = ? AND promo_active = ? AND id != ?',self.promo_start, self.promo_end, self.category_id, true, self.id]) == 0
end
def check_unique_promo_end
errors.add_to_base("End date overlaps with another promotion.") unless self.promo_active == false || Product.count(:conditions => ['promo_start BETWEEN ? AND ? AND category_id = ? AND promo_active = ? AND id != ?',self.promo_start, self.promo_end, self.category_id, true, self.id]) == 0
end
end
如果promo_active为性能,我会跳过自我。
答案 0 :(得分:1)
我会使用validates_uniqueness_of
验证:
class Product < ActiveRecord::Base
belongs_to :categories
validates_uniqueness_of :promo_active, :scope => :category_id, :allow_nil => true
before_save :update_promos
private
def update_promos
# custom code to set :promo_active to nil if the promo is
# not active and to something else if it is active
end
end
拿2:
validate :check_unique_promo
def check_unique_promo
errors.add_to_base("Only 1 promo allowed") unless Product.count(:conditions => ["active_promo = 1 AND promo_end < ?", self.promo_start]) == 0
end