2013-01-11 37 views
4

我有一個Rails應用程序,它定義了包含精度爲8和scale 2的小數的遷移。我設置的數據庫是PostgreSQL 9.1數據庫。PostgreSQL支持Rails的精度和縮放嗎?

class CreateMyModels < ActiveRecord::Migration 
    def change 
     create_table :my_models do |t| 
      t.decimal :multiplier, precison: 8, scale: 2 
      t.timestamps 
     end 
    end 
end 

當我運行rake db:migrate,遷移成功發生,但我注意到,當我嘗試運行MyModel.find_or_create_by_multiplier錯誤。如果我跑了兩次下面的命令,該對象將獲得創建兩次:

MyModel.find_or_create_by_multiplier(multiplier: 0.07) 

我假定這第一個電話時應該創建對象,然後找到第二通話過程中的對象。不幸的是,這似乎並沒有發生乘數設置爲0.07。

This DOES按照我對上述命令拋出的每個其他數字按預期工作。以下命令按預期工作(在第一次調用期間創建對象,然後在第二次調用期間找到對象)。

MyModel.find_or_create_by_multiplier(multiplier: 1.0) 

MyModel.find_or_create_by_multiplier(multiplier: 0.05) 

MyModel.find_or_create_by_multiplier(multiplier: 0.071) 

當我查看MyModel表的PostgreSQL數據庫描述時,我注意到該表對數字列沒有限制。

Column |   Type    |       Modifiers 
-------------+-----------------------------+------------------------------------------------------- 
id   | integer      | not null default nextval('my_models_id_seq'::regclass) 
multiplier | numeric      | 
created_at | timestamp without time zone | not null 
updated_at | timestamp without time zone | not null 

我的db/schema.rb文件也沒有說明精度和範圍:

ActiveRecord::Schema.define(:version => 20121206202800) do 

... 
    create_table "my_models", :force => true do |t| 
     t.decimal "multiplier" 
     t.datetime "created_at",     :null => false 
     t.datetime "updated_at",     :null => false 
    end 
... 

所以我的第一個問題是,爲什麼我看不到精度和比例下推到PostgreSQL的時候我遷移? Documentation states that it should be supported

我的第二個問題是,爲什麼0.07不能正確比較使用MyModel.find_or_create_by_multiplier(multiplier: 0.07)命令? (如果我需要爲此打開另一個問題,我會的)。

回答

7

這是尷尬...

我有精密的拼寫錯誤。

改變遷移到:

t.decimal :multiplier, precision: 8, scale: 2 

固定的一切。

+0

我甚至沒有注意到這一點。我想知道爲什麼你沒有得到一個錯誤? –

+0

我只是說同樣的事情。我回頭看看我的shell歷史記錄,除了索引通知外,輸出沒有任何說明。它基本上失敗了......仍然添加列,但忽略列的拼寫錯誤的屬性。 – Jon

+1

在我的代碼中,如果一個散列有額外的條目,我通常不會出錯... – nroose

2

PostgreSQL 9.1將允許您以任何這些方式聲明列。

column_name decimal 
column_name numeric 
column_name decimal(8, 2) 
column_name numeric(8, 2) 

如果您使用pgAdminIII來查看該列,它會向您顯示它是如何創建的。如果你(或者Rails)創建了這個列作爲numeric,它會說「數字」。如果你(或者Rails)創建了decimal(8, 2)這個列,它會說「decimal(8,2)」。

所以它看起來像我Rails沒有傳遞精度和規模到PostgreSQL。相反,它只是告訴PostgreSQL創建類型爲「numeric」的列。 Rails docs建議它應該而不是要這樣做。

該鏈接中的語法示例與您的不同。

td.column(:bill_gates_money, :decimal, :precision => 15, :scale => 2)