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