Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert User input to integer

So I have a form where users can input a price. I'm trying to make a before_validation that normalizes the data, clipping the $ if the user puts it.

before_validation do
 unless self.price.blank? then self.price= self.price.to_s.gsub(/\D/, '').to_i end
end

If user inputs $50 This code is giving me 0. If user inputs 50$ this code gives me 50. I think since the data type is integer that rails is running .to_i prior to my before_validation and clipping everything after the $. This same code works fine if the data type is a string.

Anyone have a solution that will let me keep the integer datatype?

like image 235
Robert Avatar asked Mar 13 '12 07:03

Robert


2 Answers

One way is to override the mechanism on the model that sets the price, like this:

def price=(val)
    write_attribute :price, val.to_s.gsub(/\D/, '').to_i
end

So when you do @model.price = whatever, it will go to this method instead of the rails default attribute writer. Then you can convert the number and use write_attribute to do the actual writing (you have to do it this way because the standard price= is now this method!).

I like this method best, but for reference another way to do it is in your controller before assigning it to the model. The parameter comes in as a string, but the model is converting that string to a number, so work with the parameter directly. Something like this (just adapt it to your controller code):

def create
    @model = Model.new(params[:model])
    @model.price = params[:model][:price].gsub(/\D/, '').to_i
    @model.save
end

For either solution, remove that before_validation.

like image 122
Ben Lee Avatar answered Oct 24 '22 11:10

Ben Lee


I would define a virtual attribute and do my manipulation there allowing you to format and modify both the getter and setter at will:

class Model < ActiveRecord::Base

  def foo_price=(price)
    self.price = price... #=> Mods to string here
  end

  def foo_price
    "$#{price}"
  end

You also might want to note that:

"$50.00".gsub(/\D/, '').to_i #=> 5000
like image 29
offbyjuan Avatar answered Oct 24 '22 12:10

offbyjuan