我有一个Rails应用程序,它定义了一个包含精度为8和scale 2的小数的迁移。我设置的数据库是PostgreSQL 9.1数据库。
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时似乎没有发生这种情况。
这个 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)
命令无法正确比较? (如果我需要为此打开另一个问题,我会)。
答案 0 :(得分:8)
这令人尴尬......
我精确拼写错误。
将迁移更改为:
t.decimal :multiplier, precision: 8, scale: 2
修复了一切。
答案 1 :(得分: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)
答案 2 :(得分:0)
我最初使用的是 :numeric
。尽管 ActiveRecord 为我将其更改为 :decimal
,但 :precision
和 :scale
都被忽略了。
# 202001010000000_add_my_col_to_my_table.rb
add_column :my_table, :my_col :numeric, percision: 3, scale: 2, comment: 'Foobar'
# schema.rb
t.decimal "my_col", comment: 'Foobar'
只需在迁移文件中更改为 :decimal
即可为我修复:
# 202001010000000_add_my_col_to_my_table.rb
add_column :my_table, :my_col :decimal, percision: 3, scale: 2, comment: 'Foobar'
# schema.rb
t.decimal "my_col", precision: 3, scale: 2, comment: 'Foobar'