Rails验证依赖于相关对象

时间:2014-08-16 08:37:55

标签: ruby-on-rails ruby rspec tdd

所以我正在编写我们需要发放退款的代码。我写了一个退款验证器,检查以确保退款不超过原始费用。但是,在我的规格中,我意识到相关的费用并非如此。现在还。使用FactorGirl。我怎样才能做出像这样的工作?

验证

class RefundValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    unless value <= record.charge.amount
      record.errors[:attribute] << "is greater than original charge"
    end
  end
end

验证

validates :amount, refund: true

FactoryGirl.define do
  factory :refund do
    association :client
    association :charge
    amount 99
  end
end

规格

context 'validations' do
  %i(client_id therapist_id appointment_id booking_id value).each do |attr|
    it { is_expected.to validate_presence_of attr }
  end
  it { is_expected.to validate_numericality_of(:value).is_greater_than_or_equal_to(0).is_less_than_or_equal_to(5) }
end

错误(我在存在规范中获取所有4个属性,而不仅仅是client_id):

1) Refund validations should require client_id to be set
 Failure/Error: it { is_expected.to validate_presence_of attr }
 NoMethodError:
   undefined method `amount' for nil:NilClass
 # ./app/validators/refund_validator.rb:3:in `validate_each'
 # ./spec/models/refund_spec.rb:20:in `block (4 levels) in <top (required)>'

我已尝试使用明确指定的充电工厂明确创建工厂模型,但无济于事。不知道发生了什么。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

  • 为了便于阅读,我会将unless x <= y更改为if x > y
  • 在任何情况下,您都应使用record.try(:charge).try(:amount)代替record.charge.amount来阻止验证码中的NoMethodError

如果能够解决问题,请告诉我。