Why does postgreSQL store the decimal field as a BigDecimal hash?

I have the following model / table in rails3 / postgreSQL:

create_table "admin_reports", :force => true do |t| t.string "report" t.decimal "result" t.string "result_type" t.datetime "created_at" t.datetime "updated_at" end 

In the process of creating AdminReports.result does not save the decimal, but rather the hash:

Adminminport.last

 => #<AdminReport id: 4, report: "dau", result: #<BigDecimal:cbca0f0,'0.8E1',4(8)>, result_type: "percentage", created_at: "2012-02-28 22:05:15", updated_at: "2012-02-28 22:05:15"> 

Where would I expect to see:

Adminminport.last

 => #<AdminReport id: 4, report: "dau", result: 10.10, result_type: "percentage", created_at: "2012-02-28 22:05:15", updated_at: "2012-02-28 22:05:15"> 

In the rails console, even if I try to set the result field manually like this:

 @a = AdminReport.last @a.result = 8.89 @a.save 

It still shows AdminReport.result as a BigDecimal hash. Any ideas what is going on here?

thanks

+4
source share
1 answer

You are using a decimal column:

 create_table "admin_reports", :force => true do |t| #... t.decimal "result" #... end 

This usually means that you want to use a fixed number of decimal places, so you probably want to specify the options :precision and :scale . When ActiveRecord sees the decimal column, it converts the value to Ruby BigDecimal so that you can maintain the desired number of decimal places while on Ruby-land; if AR used a floating point value, then you would encounter all the usual floating point problems, and you could pull one value out of the database and put the other back without intentionally changing it , using BigDecimal completely avoids the problem.

When you see this:

 #<BigDecimal:cbca0f0,'0.8E1',4(8)> 

You see the standard inspect output from BigDecimal. If you use to_s (or "#{...}" ), you will see something more familiar.

So there is nothing to worry about. If you need to use non-integer arithmetic, but don’t want all the problems with floating point, then the correct choice will be a decimal column (with :precision and :scale ).

+6
source

Source: https://habr.com/ru/post/1398905/


All Articles