1

好的,所以我在 Rails 4 中运行一个 Postgres 数据库,对于我的一个模型,提供属性: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 

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

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

所以我的问题是,为什么它在控制台中工作但在我的测试中失败?

4

2 回答 2

3

我不确定为什么它在测试中的行为会有所不同,但您应该注意的是,这是您的数据库default: 0的指令。它成为表定义的一部分。

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

于 2015-09-18T22:46:13.157 回答
0

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

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

于 2015-10-20T07:08:20.913 回答