blackst0ne
blackst0ne

Reputation: 721

after_find callback does not work properly

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

Answers (1)

doz87
doz87

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

Related Questions