Can FactoryBot generate factories after your models have been created?

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


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


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


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