I'm trying to remove the commas from a field in a model. I want the user to type a number, i.e. 10,000 and that number should be stored in the database as 10000. I was hoping that I could do some model-side normalization to remove the comma. I don't want to depend on the view or controller to properly format my data.
I tried:
before_validation :normalize
def normalize
self['thenumber'] = self['thenumber'].to_s.gsub(',','')
end
no worky.
http://github.com/mdeering/attribute_normalizer looks like a promising solution to this common problem. Here are a few examples from the home page:
# By default it will strip leading and trailing whitespace
# and set to nil if blank.
normalize_attributes :author, :publisher
# Using one of our predefined normalizers.
normalize_attribute :price, :with => :currency
# You can also define your normalization block inline.
normalize_attribute :title do |value|
value.is_a?(String) ? value.titleize.strip : value
end
So in your case you might do something like this:
normalize_attribute :title do |value|
value.to_s.gsub(',', '')
end
I think you're doing it right. This test passes:
test "should remove commas from thenumber" do
f = Foo.new(:thenumber => "10,000")
f.save
f = Foo.find(f.id)
assert f.thenumber == "10000"
end
And I used your code.
class Foo < ActiveRecord::Base
before_validation :normalize
def normalize
self['thenumber'] = self['thenumber'].to_s.gsub(',','')
end
end
Now, my schema is set up for thenumber to be a string though, not an integer.
Started
.
Finished in 0.049666 seconds.
1 tests, 1 assertions, 0 failures, 0 errors
If you wanted to store this in the db as an integer, then you definitely need to override the setter:
def thenumber=(value)
self['thenumber'] = value.to_s.gsub(',','').to_i
end
If you do it your way, with an integer column, it gets truncated by AR....
>> f.thenumber = "10,000"
=> "10,000"
>> f.thenumber
=> 10
That's a little-known thing with Ruby and integers... it auto-casts by truncating anything that's no longer an integer.
irb(main):004:0> i = "155-brian-hogan".to_i
=> 155
Can be cool for things like
/users/155-brian-hogan
@user = User.find_by_id(params[:id])
But not so cool for what you're doing.
So either change the col to a string and use the filter, or change the setter :)
Good luck!
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