验证属性的组合

时间:2012-11-07 03:05:59

标签: ruby-on-rails validation activerecord

我的模型(拍卖)中有两个属性(小时和天)。我有几小时和几天的商业逻辑。例如

auction duration = days*24 + hours

我还有几小时和几天的基本验证:

class Auction < ActiveRecord::Base
  validates :days,:presence => true, :numericality => { :greater_than_or_equal_to => 0, :only_integer => true }
  validates :hours,:presence => true, :numericality => { :greater_than_or_equal_to => 0, :only_integer => true }

我想将我的业务逻辑合并到验证中,这样小时和天数都不能都为零。有没有办法使用ActiveRecord验证?我知道还有其他方法可以通过AR验证来完成此任务。现在我正在创建我的模型的新实例。如上所述验证日期和时间。然后我有一个模型方法,“手动”进行验证,如果没有通过则删除实例。我知道这不是最好的方法

  def compute_end_time
    # assumes that days and hours are already valid
    time = self.days*24 + self.hours

    if time > 1
      self.end_time =  time.hours.from_now.utc
      self.save

    else
      # Auction duration too short (i.e. zero)
      self.delete
    end
  end

3 个答案:

答案 0 :(得分:2)

您需要编写类似这样的私有验证函数。

class Auction < ActiveRecord::Base
   validates :days,:presence => true, :numericality => { :greater_than_or_equal_to => 0, :only_integer => true }
   validates :hours,:presence => true, :numericality => { :greater_than_or_equal_to => 0, :only_integer => true }

   validate :days_and_hours

   private

   def days_and_hours
     if !(days && hours)
     errors.add_to_base("Days and hours can not be zero. Thank you.")
   end
 end
end

答案 1 :(得分:0)

您可以使用数值验证器检查大于0的值:

validates :auction_duration, :numericality => { :greater_than => 0 }

更多信息位于:http://guides.rubyonrails.org/active_record_validations_callbacks.html#numericality

答案 2 :(得分:0)

所以我的最终解决方案是@ rharrison33的扩展名:

  validates :days,:presence => true, :numericality => { :greater_than_or_equal_to => 0, :only_integer => true }
  validates :hours,:presence => true, :numericality => { :greater_than_or_equal_to => 0, :only_integer => true }
  validate :days_and_hours

def days_and_hours
    # It may not validate days and hours separately before validating days_and_hours,
    # so I need to make sure that days and hours are both not NIL before trying to compute 'time'
    # I also only want to compute end_time if it has not been computed yet
    if (!self.days.nil? && !self.hours.nil?)

      if (self.end_time.nil?) # if end_time has not yet been computed

        if (self.days == 0 && self.hours == 0)
          self.errors[:base] << "Days and hours can not be zero."
        else
          time =  self.hours  + self.days*24
          self.end_time = time.minutes.from_now.utc
          self.setStatus # validate status after end time is set
        end
      end
    end
  end