Can FactoryBot generate factories after your models have been created?

Ruby on-RailsRubyFactory Bot

Ruby on-Rails Problem Overview


When including the factory_bot_rails gem in your dev and test blocks in Gemfile, rails will generate factories automatically when your models are generated.

Is there a way to generate factories after your models have been generated?


Note: FactoryBot was previously named FactoryGirl

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

First thing, look at the source project to find out how it was implemented:

https://github.com/thoughtbot/factory_bot_rails/blob/master/lib/generators/factory_bot/model/model_generator.rb

After that, try to guess how it works:

rails g factory_bot:model Car name speed:integer

The result is:

create  test/factories/cars.rb

And the content:

# Read about factories at https://github.com/thoughtbot/factory_girl

FactoryBot.define do
   factory :car do
     name "MyString"
     speed 1
   end
end

Remember, when you use rails g, you can always undo it, with rails d

rails d factory_bot:model Car name speed:integer

Note: FactoryBot was previously named FactoryGirl

Solution 2 - Ruby on-Rails

The --fixture-replacement option will let you tell rails what to generate for building test data. You can set this as a default in your config/application.rb file, like so:

config.generators do |g|
  g.fixture_replacement :factory_bot, suffix_factory: 'factory'
end

Source: https://github.com/thoughtbot/factory_bot_rails/blob/master/features/fixture_replacement_config.feature#L21

Solution 3 - Ruby on-Rails

I have a gem for exactly this https://github.com/markburns/to_factory

Solution 4 - Ruby on-Rails

This works for me using rails g factory_bot:model User either running the command or just puts'ing the command out. You do still have to fill in the value.

@run_command        = true
@force              = true
@columns_to_ignore  = %w[id created_at update_at]
@tables_to_ignore = %w[schema_migrations ar_internal_metadata]
tables = ActiveRecord::Base.connection.tables.reject{|t| (@tables_to_ignore || []).include?(t)}

tables.each do |table|
  klass = table.singularize.camelcase.constantize
    command = "rails g factory_bot:model #{klass.to_s} #{klass.columns.reject do |c|
      (@columns_to_ignore || []).include?(c.name)
    end.map do |d|
      "#{d.name}:#{d.sql_type == 'jsonb' ? 'json' : d.type}"
  end.join(' ')}"
  command << ' --force' if @force
  puts command
  puts %x{#{command}} if @run_command
  puts (1..200).to_a.map{}.join('-')
end

Solution 5 - Ruby on-Rails

This is not an answer, but since I cannot comment yet: I think you can use this to solve part of your problem. You can use a gem called schema_to_scaffold to generate a factory_girl:model command string. It outputs:

rails generate factory_girl:model users fname:string lname:string bdate:date email:string encrypted_password:string

from your schema.rb or your renamed schema.rb.

Check here or here

Solution 6 - Ruby on-Rails

Configure Factory Bot as the fixture replacement so you do not have to create factories manually.

In config/application.rb:

config.generators do |g|
  g.test_framework :rspec, fixture: true
  g.fixture_replacement :factory_bot, dir: 'spec/factories'
end

For more: https://github.com/thoughtbot/factory_bot_rails/blob/master/features/fixture_replacement_config.feature

Solution 7 - Ruby on-Rails

Not exactly related.

I also built a gem to build factory from existing data.

Hopefully, it can help you speed up the process a bit......

puts FactoryBotFactory.build(User.new, file_path: 'spec/factories/user.rb')
puts FactoryBotFactory.build(User.last, file_path: 'spec/factories/user.rb')

# example output from User.new
FactoryBot.define do
  factory :user, class: User do
    id { nil }
    name { nil }
    created_at { nil }
    updated_at { nil }
    display_name { nil }
    image_url { nil }
    is_active { true }
  end
end

You can also configure customize converter if you need to built fake data.

Solution 8 - Ruby on-Rails

Some good answers here, but another option is to use stepford. For some projects that use schemas that have foreign key constraints, the deep_* methods, etc. might help, and it is a simple way to generate factories via command-line.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGuiDoodyView Question on Stackoverflow
Solution 1 - Ruby on-RailsEduardo SantanaView Answer on Stackoverflow
Solution 2 - Ruby on-RailscjhvealView Answer on Stackoverflow
Solution 3 - Ruby on-RailsMark BurnsView Answer on Stackoverflow
Solution 4 - Ruby on-RailsDavinjView Answer on Stackoverflow
Solution 5 - Ruby on-RailsfrenesimView Answer on Stackoverflow
Solution 6 - Ruby on-RailsKaka RutoView Answer on Stackoverflow
Solution 7 - Ruby on-Railsyen-jung ChenView Answer on Stackoverflow
Solution 8 - Ruby on-RailsGary S. WeaverView Answer on Stackoverflow