FactoryGirl 搞砸了 rake db:migrate 过程

FactoryGirl screws up rake db:migrate process

提问人:Ilea Cristian 提问时间:9/14/2012 更新时间:8/19/2013 访问量:9333

问:

我正在使用 Rspec (2.11.0) 和 FactoryGirl (4.0.0) 在 Ruby on Rails 3 中做 TDD/BDD。我有一个类别模型的工厂:

FactoryGirl.define "Category" do
  factory :category do
    name "Foo"
  end
end

如果我删除,创建然后迁移测试环境中的数据库,我会收到以下错误:

rake aborted!
Could not find table 'categories'

出现此问题的原因是 FactoryGirl 期望表已存在 (出于某种奇怪的原因) 。如果我从我的 rails 应用程序中删除 spec 文件夹并这样做,它可以工作。另外,如果我从我的标记,因为它也可以工作(那么我必须注释该要求才能运行 rspec)。db:migratefactory-girl-railsGemfile:require => false

我在这里找到了有关此问题的一些信息: https://github.com/thoughtbot/factory_girl/issues/88

我做错了什么吗?我怎样才能“通过”任务中的FactoryGirl阶段?db:migration

Ruby-on-Rails rspec rake bdd 工厂机器人

评论


答:

79赞 Vadym Chumel 9/14/2012 #1

我认为您需要在 Gemfile 中拥有这样的工厂女孩定义:

  gem 'factory_girl_rails', :require => false

然后你只需要在你的 spec_helper.rb 中这样:

  require 'factory_girl_rails'

这就是我一直使用这颗宝石的方式。除了 spec_helper.rb 之外,您不需要在其他地方要求它。您目前想要的方法是错误的。

评论

0赞 Vadym Chumel 9/16/2012
这个破坏你的佣金的异常是 rspec 在你运行测试时应该处理的(所以它会将规范标记为不通过)。你的方法是错误的,因为它不能按照你想要的方式工作。
0赞 Geesu 10/25/2013
我遇到了这个确切的问题,这解决了它 - 非常感谢!
0赞 Waseem 5/21/2014
我在迷你裙宝石上遇到了同样的问题。这个答案也解决了迷你裙的问题。
0赞 whales 10/7/2016
@VadimChumel 你介意解释一下为什么添加 :require => false 会使错误消失吗?我在存储库中找不到有关此选项的任何文档。此外,就像 OP 所说,添加此选项会导致运行 rspec 时出错。有更好的解决方案吗?
0赞 erosenin 2/26/2018
@whales 它修复了它,因为之前需要 gem 会让它加载 gem 需要的文件,而这些文件恰好是 factories.rb。由于该表不存在,如果工厂文件尝试加载类 Category,并且在加载类时,如果某些内容需要该表存在,它将出错。当您运行 rspec 时,您可以在之前要求它,然后如果表存在,它应该能够很好地加载工厂。
3赞 Ilea Cristian 9/14/2012 #2

信息来源:http://guides.rubyonrails.org/testing.html

当你最终破坏了你的测试数据库时(相信我,它会发生), 您可以根据开发中定义的规范从头开始重建它 数据库。您可以通过运行 来执行此操作。rake db:test:prepare

上述方法在开发环境中运行任何挂起的迁移 和更新。从 当前。在后续尝试中,最好先运行 ,因为它首先检查挂起的迁移并相应地警告您。rake db:migratedb/schema.rbrake db:test:loaddb/schema.rbdb:test:prepare

rake db:test:clone            Recreate the test database from the current environment’s database schema
rake db:test:clone_structure  Recreate the test database from the development structure
rake db:test:load             Recreate the test database from the current schema.rb
rake db:test:prepare          Check for pending migrations and load the test schema
rake db:test:purge            Empty the test database.
12赞 polm23 12/10/2012 #3

解决此问题的简单方法是将工厂中的任何模型包装在块中,从而延迟对它们的评估。所以,而不是这个:

factory :cake do
  name "Delicious Cake"
  frosting Frosting.new(:flavor => 'chocolate')
  filling Filling.new(:flavor => 'red velvet')
end

这样做(注意大括号):

factory :cake do
  name "Delicious Cake in a box"
  frosting { Frosting.new(:flavor => 'chocolate') }
  filling { Filling.new(:flavor => 'red velvet') }
end

如果你有很多工厂,这可能不可行,但它相当简单。另请参阅此处

评论

0赞 LisaD 9/9/2015
我需要这个答案(尽管我也应用了有关在 factory_girl Gemfile 列表中设置 require=false 的建议。在创建表之前,FactoryGirl 尝试在加载环境时创建对象。
0赞 grepsedawk 2/15/2017
这是最终为我修复它的答案。
1赞 Urkle 2/12/2013 #4

你不需要做任何事情。我认为问题是你对 FactoryGirl.define 的论点。

试试这个。

FactoryGirl.define do
   factory :category do
       name "Foo"
   end
end

这应该可以正常工作,并且不会搞砸我的迁移或负载。今天,我必须解决一个问题,即我直接引用了工厂中的模型常量,并且必须将其放在一个块中以解决问题。

FactoryGirl.define do
   factory :category do
       # this causes unknown table isseus
       # state Category::Active
       # this does not.
       state { Category::Active }
   end
end