Я использую Rails 3 с гемом client_side_validations, что означает, что мне нужен Regexp, который работает как в Ruby, так и в Javascript.У меня также есть четкое разграничение между внешним интерфейсом и внутренним форматом - пользователь никогда не должен иметь возможность вводить «$ 12,5», но как только он попадет на сервер, меня не волнует конечный 0. 0. 1001 *
Мое решениеЯ должен был добавить расширение ядра (в моем случае, для Float, но BigDecimal, вероятно, было бы более подходящим в большинстве случаев):
class Float
def can_convert_to_i_with_no_loss_of_precision
(self % 1).zero?
end
alias_method :to_s_with_loss_of_trailing_zeroes, :to_s
def to_s
if can_convert_to_i_with_no_loss_of_precision
to_i.to_s
else
"#{to_s_with_loss_of_trailing_zeroes}#{0 if (self * 10 % 1).zero?}"
end
end
end
Теперь я могу использовать это в модели, и он хорошо играет навнешний интерфейс (Javascript не преобразует его в число с плавающей точкой, поэтому пользователь всегда будет вынужден вводить 2 цифры после десятичной дроби) и на внутренней стороне (где FormatValidator в ActiveModel будет вызывать to_s
, а расширение ядра будет знать, когда добавитьконечный 0):
validates :price, :format => { :with => /^\d+(\.\d{2})?$/, :allow_blank => true }