Точность с плавающей точкой в ​​ruby ​​на валидациях - PullRequest
5 голосов
/ 04 мая 2010

Я пытаюсь проверить сумму в долларах с помощью регулярного выражения: ^[0-9]+\.[0-9]{2}$

Это работает нормально, но всякий раз, когда пользователь отправляет форму, а сумма в долларах заканчивается на 0 (ноль), рубин (или рельсы?) Отключает 0. Таким образом, 500,00 превращается в 500,0, таким образом, не проходит проверку регулярного выражения.

Есть ли способ заставить ruby ​​/ rails сохранять введенный пользователем формат независимо от конечных нулей?

Ответы [ 3 ]

8 голосов
/ 04 мая 2010

Я предполагаю, что ваша сумма в долларах имеет десятичный тип. Таким образом, любое значение, введенное пользователем в поле, преобразуется из строки в соответствующий тип перед сохранением в базе данных. Валидация применяется к значениям, уже преобразованным в числовые типы, поэтому регулярное выражение на самом деле не является подходящим фильтром проверки в вашем случае.

У вас есть несколько способов решить эту проблему, однако:

  1. Используйте validates_numericality_of. Таким образом, вы полностью оставляете конвертацию в Rails и просто проверяете, находится ли сумма в заданном диапазоне.
  2. Используйте метод validate_each и кодируйте свою логику проверки самостоятельно (например, проверьте, имеет ли значение более 2 десятичных цифр).
  3. Проверка атрибута до его типизации :

Это особенно полезно в проверки ситуаций, когда пользователь может предоставить строку для целого числа поле, и вы хотите отобразить исходная строка вернулась с ошибкой сообщение. Доступ к атрибуту обычно вводит строку в 0, что не то, что вы хотите.

Итак, в вашем случае вы сможете использовать:

validates_format_of :amount_before_type_cast, :with => /^[0-9]+\.[0-9]{2}$/, :message => "must contain dollars and cents, seperated by a period"

Обратите внимание, однако, что пользователям может показаться утомительным следовать вашим жестким правилам ввода (я бы действительно предпочел иметь возможность набирать 500 вместо 500.00, например), и что в некоторых локалях период не является десятичным разделитель (если вы планируете интернационализировать свое приложение).

2 голосов
/ 04 мая 2010

В общем, если вы хотите «запомнить» десятичную точность значения с плавающей запятой, вы должны использовать тип десятичный , а не двоичный тип с плавающей запятой.

С другой стороны, я не уверен, почему вы захотите заставить строковое представление таким строгим образом ... Как насчет принятия любого числа и форматирования его, например, с помощью. number_to_currency

0 голосов
/ 04 мая 2010

Обычно с деньгами лучше хранить их как целые числа в центах (500 центов - 5,00 долларов США). Я использую Money gem , чтобы справиться с этим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...