问题
I am doing TDD/BDD in Ruby on Rails 3 with Rspec (2.11.0) and FactoryGirl (4.0.0). I have a factory for a Category model:
FactoryGirl.define "Category" do
factory :category do
name "Foo"
end
end
If I drop, create then migrate the database in the test enviroment I get this error:
rake aborted!
Could not find table 'categories'
This problem occurs because FactoryGirl expects the tables to already exist (for some odd reason). If I remove the spec folder from my rails app and do db:migrate
, it works. Also if I mark factory-girl-rails
from my Gemfile
as :require => false
it also works (then I have to comment that require in order to run rspec).
I found some information about this problem here: https://github.com/thoughtbot/factory_girl/issues/88
Is there something wrong that I'm doing? How can I "pass by" the FactoryGirl stage in the db:migration
task?
回答1:
I think you need to have factory girl definition like that in Gemfile:
gem 'factory_girl_rails', :require => false
And then you just require it in your spec_helper.rb like that:
require 'factory_girl_rails'
This is the way I'm always using this gem. You don't need to require it in other places than spec_helper.rb. Your current desired approach is just wrong.
回答2:
A simple fix to this issue is to delay evaluation of any models in your factories by wrapping them in blocks. So, instead of this:
factory :cake do
name "Delicious Cake"
frosting Frosting.new(:flavor => 'chocolate')
filling Filling.new(:flavor => 'red velvet')
end
Do this (notice the curly braces):
factory :cake do
name "Delicious Cake in a box"
frosting { Frosting.new(:flavor => 'chocolate') }
filling { Filling.new(:flavor => 'red velvet') }
end
If you have a lot of factories this may not be feasible, but it is rather straightforward. See also here.
回答3:
Information from: http://guides.rubyonrails.org/testing.html
When you do end up destroying your testing database (and it will happen, trust me),
you can rebuild it from scratch according to the specs defined in the development
database. You can do this by running rake db:test:prepare
.
The rake db:migrate
above runs any pending migrations on the development environment
and updates db/schema.rb
. The rake db:test:load
recreates the test database from the
current db/schema.rb
. On subsequent attempts, it is a good idea to first run db:test:prepare
, as it first checks for pending migrations and warns you appropriately.
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.
回答4:
You shouldn't need to do any of that.. I think the issue is that your argument to FactoryGirl.define..
try this.
FactoryGirl.define do
factory :category do
name "Foo"
end
end
That should work fine, and does not screw up my migrations or load.. Today, I had to fix an issue where I was referencing a model constant from my factory directly and had to put it in a block to fix things.
FactoryGirl.define do
factory :category do
# this causes unknown table isseus
# state Category::Active
# this does not.
state { Category::Active }
end
end
来源:https://stackoverflow.com/questions/12423273/factorygirl-screws-up-rake-dbmigrate-process