Вам нужно пересмотреть вопрос о том, что является вашей реальной проблемой.Особенностью Rails является то, что строка автоматически преобразуется либо в соответствующее десятичное значение, либо в 0.0 в противном случае.
Что происходит
1) Вы можете сохранитьчто-нибудь в поле ActiveRecord.Затем он преобразуется в соответствующий тип для базы данных.
>> product.price = "a"
=> "a"
>> product.price
=> #<BigDecimal:b63f3188,'0.0',4(4)>
>> product.price.to_s
=> "0.0"
2) Следует использовать правильную проверку, чтобы убедиться, что хранятся только действительные данные.Что-то не так с сохранением значения 0?Если нет, то вам не нужна проверка.
3) Вам не нужно проверять, что число будет храниться в базе данных.Поскольку вы объявили поле db десятичным, оно будет содержать ТОЛЬКО десятичные дроби (или ноль, если вы позволите полю иметь нулевые значения).
4) Ваша проверка была строковой проверкой.Таким образом, регулярное выражение проверки изменило значение 0.0 BigDecimal на "0.0", и оно прошло вашу проверку.Почему вы думаете, что ваша проверка была обойдена?
5) Почему именно вас беспокоит то, что другие программисты хранят строки в вашем ценовом поле?
Вы пытаетесь избежать ошибочной установки продуктов на нулевую цену? Есть несколько способов обойти это.Вы можете проверить значение по мере его поступления (до того, как оно будет преобразовано в десятичное), чтобы убедиться, что его формат правильный.См. AR Раздел «Перезапись доступа по умолчанию»
Но я думаю, что это будет грязно и подвержено ошибкам.Вы должны будете установить Error obj записи из Setter или использовать флаг.А простая проверка классов не сработает, помните, что данные формы всегда отображаются в виде строки.
Рекомендуется Вместо этого заставьте пользователя подтвердить, что он хотел установить цену 0 дляпродукт с использованием дополнительного поля только для AR (поле, которое не хранится в DBMS).
Например
attr_accessor :confirm_zero_price
# Validate that when the record is created, the price
# is either > 0 or (price is <= 0 && confirm_zero_price)
validates_numericality_of :price, :greater_than => 0,
:unless => Proc.new { |s| s.confirm_zero_price},
:on => :create
Примечания Выше приведен видвещь, которую ОЧЕНЬ важно включить в свои тесты.
Также У меня были подобные ситуации в прошлом.В результате моего опыта я теперь записываю в базу данных имя человека, который сказал, что значение действительно должно быть $ 0 (или отрицательным), и пусть у них есть поле причины 255 символов для их обоснования.Позволяет сэкономить много времени, когда люди задаются вопросом, в чем причина.