How can I use FactoryBot in db/seeds?
Asked Answered
S

6

36

Is it possible to do this?

If so, how can you do it?

Note: FactoryBot was previously named FactoryGirl

Semibreve answered 21/3, 2011 at 18:59 Comment(1)
db/seeds.rb should contain production specific core data that your site needs to run. Factories should only be used in your tests, helping you execute operations in isolation. Are you just trying to make your db/seeds shorter or something?Cape
A
15

(This answer works in rails 3.0.7)

I found the catch is how you set up the Gemfile - you need to do something along the lines of

gem 'factory_girl'

group :test do
  gem 'factory_girl_rails'
end

We found problems having factory_girl_rails outside of the :test environment, which we didn't manage to get to the bottom of (maybe something to do with the way rails does class caching?)

Once that is done, I like to actually load data from a library in lib, something like...

require 'factory_girl'
require 'spec/factories/user_factory'

module Seeds

  class SampleUsers

    def self.run
    u = Factory(:user)
  end
end

And then running this method from within db:seed using

Seeds::SampleUsers.run
Algar answered 11/5, 2011 at 10:7 Comment(3)
See hubble's comment on Michael's answer for an alternate way of making the Gemfile work. It seems factory_girl_rails is safe to require in db/seeds but shouldn't be auto-required by Rails through Bundler. To keep that from happening hubble sets :require => false.Emikoemil
Great answer! Just what I needed. I found that I would get errors if I had the two require statements. So I don't have them in my implementation.Quantitative
In Rails 4, this is no longer necessary: you can get away with group :development, :test do gem 'factory_girl_rails' Then just require 'factory_girl_rails' in lib/tasks/sample_data.rake.Scoria
T
31

All you need to do is add require 'factory_bot_rails' to the db/seeds.rb file. This will give you access to your factories.

Note: Gem was previously called FactoryGirlRails

Tye answered 13/9, 2011 at 12:43 Comment(1)
This is great, but make sure :require => false is in your Gemfile for factory_girl_rails, otherwise it causes initialization dependency issues when you try to db:migrate and the factories represent models you haven't migrated yet. -- And then you'll need to require 'factory_girl_rails' in your spec_helper after that.Orit
C
18

Josh Clayton, the maintainer of FactoryGirl, recommends against using FactoryGirl in your seeds file. He suggests using plain ActiveRecord instead.

Cloying answered 14/11, 2013 at 4:20 Comment(2)
One good argument for wanting to use Factory Girl in seeds is that our ActiveRecord seeds keep breaking every time someone updates the API. It breaks without warning. To guard against that we want the seed file to be test covered. Factory Girl can help with both seeding and testing.Turnout
I never quite understood that article.. My guess is they refer to using it only for that purpose. If you already have several factories used for testing, that you already keep up to date it makes a lot of sense to reuse them instead of rewriting that logic.Priggish
A
15

(This answer works in rails 3.0.7)

I found the catch is how you set up the Gemfile - you need to do something along the lines of

gem 'factory_girl'

group :test do
  gem 'factory_girl_rails'
end

We found problems having factory_girl_rails outside of the :test environment, which we didn't manage to get to the bottom of (maybe something to do with the way rails does class caching?)

Once that is done, I like to actually load data from a library in lib, something like...

require 'factory_girl'
require 'spec/factories/user_factory'

module Seeds

  class SampleUsers

    def self.run
    u = Factory(:user)
  end
end

And then running this method from within db:seed using

Seeds::SampleUsers.run
Algar answered 11/5, 2011 at 10:7 Comment(3)
See hubble's comment on Michael's answer for an alternate way of making the Gemfile work. It seems factory_girl_rails is safe to require in db/seeds but shouldn't be auto-required by Rails through Bundler. To keep that from happening hubble sets :require => false.Emikoemil
Great answer! Just what I needed. I found that I would get errors if I had the two require statements. So I don't have them in my implementation.Quantitative
In Rails 4, this is no longer necessary: you can get away with group :development, :test do gem 'factory_girl_rails' Then just require 'factory_girl_rails' in lib/tasks/sample_data.rake.Scoria
K
14

in db/seeds.rb

require 'factory_girl_rails'

10.times do
  FactoryGirl.create :user
end
Kevenkeverian answered 14/6, 2013 at 22:10 Comment(1)
FactoryGirl.create_list(:user, 10)Rowdyism
E
3

In Rails 5.2.6, you can create factories in your db/seeds.rb file. Add include FactoryBot::Syntax::Methods at the top of your seeds.rb file. Below that line, you can create your factories – i.e. user1 = create(:user).

# db/seeds.rb
include FactoryBot::Syntax::Methods

user1 = create(:user)
Expeditionary answered 18/9, 2021 at 16:34 Comment(1)
This works great! The only potential consideration is to have your factories in some other location than spec/factoriesSaltsman
A
2

You can insert the following code into your spec_helper.rb, and it make some instances of the data you want (in this case "products" from the yaml file):

seeds_file = File.join(Rails.root, 'db', 'seeds.yml')
config = YAML::load_file(seeds_file)
config["products"].each do |product|
  FactoryGirl.create(:product, product) if !Product.find_by_name(product['name'])    
end
Awash answered 4/4, 2011 at 16:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.