2010-05-07 62 views
0

拥有属于某个类别的产品。想要在短时间内创建促销活动(可以说是一周或两周),但在此期间,它们只能针对每个类别进行一次促销。Ruby复制验证

如何为此创建自定义验证?

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

如此做更新的代码工作? – 2010-05-09 15:04:35

+0

似乎。现在测试。看起来就像我把它归结为min,但用日期做数据库查询并不有趣,似乎给我带来了很多与时区有关的问题。看到你的代码如何导致答案,我将其标记为正确。 – pcasa 2010-05-09 15:08:29

回答

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 
+0

需要为显示最近宣传片的其他页面保留以前宣传的项目。你能推荐一些相同的东西,但可以在数据库中搜索结束日期在开始日期之前的任何其他“活动”产品吗? – pcasa 2010-05-07 21:36:55

+0

恐怕我不明白你的评论。你能澄清一下问题是什么? – 2010-05-07 22:15:24

+0

不能真正离开这个领域为零。我用它来看另一个视图。我需要找到一种方法来执行数据库查询,其中包括:具有相同的:catagory_id的active_promo,其中包含:promo_end promo_end或promo_start :category_id – pcasa 2010-05-08 02:37:48