Best way to handle Fixed point/ percision decimal in Ruby on Rails
So I am creating a time tracking application using Ruby On Rails and am storing the time as a number representing hours.
Since anything beyond 0.01 (36 seconds ) hours is irrelevant I only need 2 decimal places.
I am using a MySQL database with a float as the column type. While this works most of the time, every now and then i get an error with the calculation and rounding of floats.
I have done some research into my options and see that a lot of people recommend using BigDecimal. Since I use a lot of custom Database querys using calculations, so I wanted to know how changing the column type would affect this. Does it store this as a string or yaml, or is it natively supported by MySQL?
Or is ther开发者_高级运维e an equivalent way to do fixed-point decimal arithmetic in Ruby / Rails.
I assume any method is going to require much refactoring, how can I avoid this the most?
Any insight is appreciated.
Instead of storing the time as a number representing hours, store it as a number representing increments of 36 seconds (or maybe individual seconds).
You shouldn't need a decimal supporting type to do fixed-point, simply divide in the business logic to get hours.
MySQL does have built-in BigDecimal support. http://dev.mysql.com/doc/refman/5.1/en/precision-math-decimal-changes.html
I would suggest using that; it works well in my Rails applications. Allowing the database to handle that instead of the application makes life easier - you're using the abstractions the way they're designed.
Here's the migration code:
change_column :table_name, :column_name, :decimal
Reference: Rails migration for change column
We have actually build a time tracking app (http://www.yanomo.com) and store all our times as the number of hours they represent with MySQL as the underlying dbms. For the column type we use DECIMAL(precision,scale). In your case something like DECIMAL(5,2) would do. In our businesslogic (JAVA) we use BigDecimal.
精彩评论