Rails 3 复杂的验证设计

Rails 3 complicated validation design

我有一个 ContributionReward 模型。一个贡献 belongs_to 一个奖励。我希望贡献只有其金额大于其奖励的 minimum_contribution.

才有效

所以我有

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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。在运行此验证之前,我需要确保

  • 贡献的有效定义(甚至是数字)。否则在 unless value > reward.minimum_contribution 中比较会出错,因为你不能与 nil 比较
  • 贡献的奖励被定义
  • 贡献的奖励的 minimum_contribution 是定义的和数字的
  • 我应该在 SOMECONDITION 的 lambda 中做这一切吗?有这么多守卫来进行一次验证,这让人感觉有些不对劲。我是否正确设计了这个?在我的验证中抛出异常是否正确的设计,例如 unless amount > contribution.reward.minimum_contributionamount 实际上是 nil? (很明显,我总是希望数量是数字,但我不确定我应该在验证中有多偏执/我可以信任什么)


    您可以将 validates_each :amount 替换为:

    1
    2
    3
    4
    5
    6
    7
    ...
    validate :validate_mininum_amount

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

    注意:如果是 nil,添加 .to_i 可确保金额为 0。或者,您可以为 nil 添加特定检查。在 validate_mininum_amount 方法中添加您需要的任何其他检查。