Here's what I'm using in my model:
before_validation :strip_dollar_sign
validates :amount_due,
:format => { :with => /^\d+??(?:\.\d{0,2})?$/ },
:numericality => {:greater_than => 0}
private
def strip_dollar_sign
self.amount_due = self.amount_due.to_s.tr!('$,','').to_f
end
If I run the line from the strip_dollar_sign function by hand in the Rails Console I get exactly what I want (i.e. $400 ends up as 400.0) but when I use the actual form in my app the value always ends up as 0.0. Anybody catch what I'm doing wrong?
Three problems here:
As pointed out by Stefan in his answer, you may want to remove the ,
in your tr!
call, though it won't affect the replacement of a $
.
You're using tr!
, and are using its return value in an incorrect way. tr!
(along with most of Ruby's !
method variants) mutates the string in-place and returns nil
if no changes were made. Since nil.to_f
is 0.0
, that's why you're getting that (or maybe not, see below). You should instead use tr
.
Rails automatically converts assignment arguments to the correct type for the database column associated with it, so even before validation your value is being converted to a float, and "$400".to_f
is 0.0
, and that's what your callback sees. The solution is to override amount_due=
instead of using a callback:
def amount_due=(value)
value = value.to_s.tr('$', '').to_f
write_attribute(:amount_due, value)
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With