ActiveRecord#在运行规范时返回实例

时间:2013-05-28 17:54:18

标签: ruby-on-rails activerecord rspec rspec-rails

我正在为某些软件编写规范并得到一个奇怪的行为:在我正在测试的方法中,我正在调用:

MyModel.where(special_identifier: opts[:ident]).first || MyModelBuilder.new(m).build 

(注意我不想要first_or_create或first_or_new,因为我在这里使用显式构建器)。当我查询MyModel.where(...)时,我应该返回一个ActiveRecord::Relation对象,这是它在prod,dev,console等中的行为。但是,在运行规范时,where会返回{ {1}}对象。这是一个错误,我错过了什么吗?

2 个答案:

答案 0 :(得分:1)

听起来你的数据库中有状态。警惕可导致此问题的before(:all)块。也可以考虑类似database_cleaner gem。

答案 1 :(得分:1)

正如@DVG在评论中所说,MyModel.where(...)会返回一个关系,但是在其上调用.first.last应该返回一个实例,而不是关系。同样,如果where返回多个记录,则关系上的.limit(...).to_a.all将返回记录集。

如果你正在做MyModel.where(...)并且它肯定没有返回关系,那么你需要弄清楚发生了什么:

if !MyModel.where('').is_a? ActiveRecord::Relation
  raise "where was defined in #{MyModel.method(:where).source_location}"
end

如果在规范中,那么加注可能是fail

如果这不起作用,请参阅this answer了解更多获取方法来源的方法。

现在,如果.first返回nil,则代码为:

MyModel.where(special_identifier: opts[:ident]).first || MyModelBuilder.new(m).build

将返回MyModelBuilder.new(m).build返回的任何内容(或者它可能会引发某些内容)。