0

I have a form that has a group of 3 text_fields. I need two of them filled to make calculations. quantity must always be filled. If price is blank, then cost must be filled, or vice versa.

I tried this, but price is never nil, even though I leave it blank. I also tried :price == nil and :price.blank?, but they do the same thing.

# app/models/item.rb

validates_numericality_of :cost, :greater_than => 0

if :price.nil?
  validates_numericality_of :quantity, :greater_than => 0
else
  validates_numericality_of :price, :greater_than => 0
end

1 Answer 1

2

The code in the question is trying to define class methods based on instance variables. There's no way this will work. Also :price is just a symbol. It can never have any value beyond it's internal value. The following results in syntax errors:

:price = nil
:price = anything

Symbols are always defined and have an internal value, which is set to the text the string after the ':'. Meaning :price.nil? and :price == nil will never be true. You're getting confused because you see :price passed to other class methods. What's really happening is that those methods take the symbol and dynamically turn into an instance method name to be called, a column name when executed, or just uses it as a key in a hash.

Enough about why what you were doing doesn't work. Let's talk about how to fix it.

You want to use the if and unless clauses for validations. This code does exactly what you want.

# app/models/item.rb
validates_numericality_of :cost, :greater_than => 0

  validates_numericality_of :quantity, :greater_than => 0,
    :if => Proc.new {|item| item.price.nil?}
  validates_numericality_of :price, :greater_than => 0, 
    :unless => Proc.new {|item| item.price.nil?}
end
Sign up to request clarification or add additional context in comments.

1 Comment

Sorry, that should have been Proc.new before the blocks. Fixed now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.