Код в вопросе пытается определить методы класса на основе переменных экземпляра. Это никак не сработает. Также: цена это просто символ. У него никогда не может быть никакой ценности, кроме внутренней. Следующие результаты приводят к синтаксическим ошибкам:
:price = nil
:price = anything
Символы всегда определены и имеют внутреннее значение, которое задается в тексте строкой после ':'. Значение :price.nil?
и :price == nil
никогда не будет правдой. Вы запутались, потому что видите: цена перешла к другим методам класса. На самом деле происходит то, что эти методы принимают символ и динамически превращаются в имя вызываемого метода экземпляра, имя столбца при выполнении или просто используют его в качестве ключа в хэше.
Достаточно о том, почему то, что вы делали, не работает. Давайте поговорим о том, как это исправить.
Вы хотите использовать операторы if и else для проверок . Этот код делает именно то, что вы хотите.
# 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