Вопрос

When I use Shoulda's validates_presence_of, it stumbles on a before_validation callback.

before_validation   :set_document, :set_product, :set_price

I'm trying to get this spec to pass:

it { should validate_presence_of(:quantity).with_message("Please a quantity.") }

I have database defaults of 0 for a line item's quantity, unit_price, tax_rate, and price. Before a line item is validated I compute the price from the other attributes in case they have changed.

I get this error, and similar errors, for all of the attributes involved in this computation:

3) LineItem 
   Failure/Error: it { should validate_presence_of(:quantity).with_message("Please a quantity.") }
   NoMethodError:
     undefined method `*' for nil:NilClass
   # ./app/models/line_item.rb:153:in `total_price'
   # ./app/models/line_item.rb:223:in `set_price'
   # ./spec/models/line_item_spec.rb:32:in `block (2 levels) in <top (required)>'

My callback, set_price, is very simple:

def set_price
  self.price = total_price
end

And the total_price method is very simple as well:

def total_price
  quantity * unit_price * (1 + tax_rate/100)
end

I'd appreciate any help with this one as I'm completely stumped. I did see some people post about custom validation methods. This seems so basic I can't figure it out how to proceed.

Это было полезно?

Решение

Since total_price runs before validation, quantity can be nil at the time the callback is executed. This is in fact what happens behind the scenes when the Shoulda matcher runs, which is why you get an error. It's trying to send the * method to quantity, which is nil.

Use after_validation or before_save instead.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top