Rails 3复杂的验证设计

时间:2012-07-15 04:46:42

标签: ruby-on-rails validation associations

我有一个ContributionReward型号。贡献belongs_to奖励。我希望捐款有效只有其金额大于奖励的minimum_contribution

所以我有

Class Contribution < ActiveRecord::Base
  attr_accessible :reward_id, :reward
  belongs_to :reward

  validates_presence_of :amount
  validates_numericality_of :amount, greater_than: 0
  validates_presence_of :reward

  validates_each :amount, unless: SOMECONDITION do |contribution, attr, amount|
    reward = contribution.reward
    contribution.errors.add(attr,
                            "Contribution must be at least #{reward.minimum_contribution}") unless amount > reward.minimum_contribution
  end
end

我的问题是适合SOMECONDITION的问题。在运行此验证之前,我需要确保

  1. 定义了贡献的有效(甚至是数字)。否则,在unless value > reward.minimum_contribution中进行比较会出错,因为您无法与nil进行比较
  2. 定义了贡献的奖励
  3. 贡献奖励的minimum_contribution已定义且数字
  4. 我应该在SOMECONDITION的lambda中执行此操作吗?有这么多警卫进行单一验证的事情是错误的。我正确地设计了吗?在我的验证中抛出异常是不合适的设计,例如unless amount > contribution.reward.minimum_contributionamount实际为nil时? (显然我总是期望金额是数字,但我不确定我在验证中应该是多么偏执/我可以信任的是什么)

1 个答案:

答案 0 :(得分:1)

您可以将validates_each :amount替换为:

...
validate :validate_mininum_amount

def validate_mininum_amount
  errors.add :amount, "some error message" if amount.to_i < reward.min_contribution
end
...

注意:添加.to_i可确保金额为0 nil。或者你可以添加一个特定的检查nil。使用validate_mininum_amount方法添加您需要的任何其他支票。