How can I manipulate a decimal or integer column in a callback before saving to database
I am having a model Factsheet
which has some decimal columns, for entering some $ values(price). I need to be able to enter values like $1,000,000.00
and calculate the original value from them before saving. If I do the save, before any formatting, it will save it as 1.00
as "$1,000,000.00".to_f = 1.0
I was trying to do a before_save callback, and extract the digits and dots only from the column before saving it. Here is how I went about it:
class Factsheet < ActiveRecord::Base
before_save :convert_to_decimal
def convert_to_decimal
self.shopping_center_size = decimal_value(shopping_center_size)
self.cam = decimal_value(cam)
self.tax = decimal_value(tax)
#... some other manipulations
end
def decimal_value(string)
string ? string.gsub(/[^\d\.]/, "") : string
end
end
But, this code is not working as Rails convert the parameters into BigDecimal
(I believe it performs to_f
to the string). So I am getting NoMethod gsub for BigDecimal
when I execute this code. I know I can manipulate the params
in the controller itself before saving, or pass the params
to a class method in the model and开发者_JS百科 manipulate it there. But, both these options doesnt seem right. Is there anyway, I can manipulate them in the callback itself?
Controller:
def FactsheetsController < ApplicationController
def new
@factsheet = Factsheet.new
end
def create
@factsheet = Factsheet.new(params[:factsheet])
if @factsheet.save
flash[:notice] = "Factsheet created successfully"
redirect_to @factsheet
else
render :action => "new"
end
end
def edit
@factsheet = Factsheet.find(params[:id])
end
def update
@factsheet = Factsheet.find(params[:id])
if @factsheet.update_attributes(params[:factsheet])
flash[:notice] = "Factsheet updated successfully"
redirect_to @factsheet
else
render :action => "edit"
end
end
end
View:
_form.html.erb
# Here user should be able to enter values like $1,000,000.00
# and it should be correctly saved to database as 1000000.0
<%= form.text_field :cam %>
<%= form.text_field :tax %>
You can override the set method of each field in the model, like this:
def shopping_center_size=(num)
self[:shopping_center_size] = decimal_value(num)
end
def cam=(num)
self[:cam] = decimal_value(num)
end
def tax=(num)
self[:tax] = decimal_value(num)
end
精彩评论