Reputation: 721
I have Rails 4.1.6 installed.
Model Report
:
after_find :convert_decimal_to_float
def convert_decimal_to_float
self.mag = self.mag.to_f
end
In rails console:
2.1.2 :001 > r = Report.last
...
2.1.2 :002 > r.mag
=> #<BigDecimal:5032730,'0.31E1',18(36)>
But if I use r.mag.to_f
, it works fine:
2.1.2 :003 > r.mag.to_f
=> 3.1
The question is, why doesn't my after_find callback work properly here?
Upvotes: 1
Views: 100
Reputation: 601
Your after_find callback is actually working properly but because your database column is of type DECIMAL it will always save as BigDecimal. Just as if the column was of type FLOAT then if you tried to save a BigDecimal number to it, it will convert and save as a floating point number.
Without knowing exactly why you require the conversion upon "finding" your object, its hard to give any advice as to a appropriate workaround but here are a couple of options:
First Option:
You can create two columns in your database. A DECIMAL column and a FLOAT column.
Migration
add_column('report','mag', :decimal,:precision => 11, :scale => 9) # I've just used random precision and scale, I'm not sure what you would need
add_column('report','mag_floating_point', :float)
Report Model
after_find :convert_decimal_to_float
def convert_decimal_to_float
self.mag_floating_point = self.mag # this will convert decimal number to float and "Assign"
self.save # you will still need to save the object as the value has only been assigned
end
Second Option:
The second option which I think would be alot better.
Report Model
attr_accessor :mag_floating_point # Virtual attribute
def convert_decimal_to_float
self.mag_floating_point = self.mag.to_f
end
You will now be able to access the floating point through your virtual attribute but keep in mind that it wont persist. In my opinion, this is much cleaner.
Upvotes: 1