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 yourtr!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 returnsnilif no changes were made. Sincenil.to_fis0.0, that’s why you’re getting that (or maybe not, see below). You should instead usetr.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_fis0.0, and that’s what your callback sees. The solution is to overrideamount_due=instead of using a callback: