Rails 测试数据库中的默认值失败

Rails Testing Default Value in database fails

好的,所以我是 运行 Rails 4 中的一个 Postgres 数据库,对于我的一个模型 Offer 属性 :offer_status 应该默认为拒绝。这是我的迁移:

def change
    create_table :offers do |t|
      t.integer :offer_status, default: 0

      t.timestamps null: false
    end

:offer_status 属性引用模型中的枚举,如下所示:

class Offer < ActiveRecord::Base
 enum offer_status: [:declined, :accepted]
end 

有了这两个,我编写了一个测试来检查新创建的商品是否具有默认的 offer_status 0。

 test "new offers should default to declined" do
    @offer2=Offer.new()
    assert @offer2.declined?
  end

当我在测试中调用 byebug 控制台并输入 @offer2 时,我得到了这个:

(byebug) o
<Offer id: nil,  offer_status: nil, created_at: nil, updated_at: nil>
(byebug) exit 

但是,如果我在 rails 控制台中执行完全相同的调用 o=Offer.new() returns:

 2.2.0 :001 > o=Offer.new
 => #<Offer id: nil, offer_status: 0, created_at: nil, updated_at: nil> 

所以我的问题是,为什么它在控制台中有效但在我的测试中却失败了?

我不确定为什么它在测试中表现不同,但您应该注意的是,default: 0 是针对您的 数据库的指令.它成为 table 定义的一部分。

调用 new 将创建一个新的 ruby 对象实例,在您尝试保存它之前不会触及数据库。定义默认值只是告诉数据库“如果您没有收到此列的值,请将 0 放入其中”-但是直到您通过 SQL 查询将带有保存的新对象发送到数据库之前,这将具有对你的对象绝对没有影响。

我刚刚遇到了类似的问题。我必须更改已执行的迁移(将默认值添加到 0 并指定 null: false)。我执行了 rake db:rollback STEP=1 然后我重新运行 迁移。一切正常,在 rails 控制台中,我能够看到对于每个创建的对象,该属性的默认值是 0,但在测试中它总是 nil。它为我解决的问题是删除数据库(那里没有重要数据),重新创建它,运行 迁移和测试的执行没有失败或错误。

也许我应该提一下,甚至在我删除数据库之前,在该列的 schema.db 中,默认值已经是 0 和 null: false。也许 rake test 使用不同的模式,缓存的东西,而不是最新的...