Skip to content

Instantly share code, notes, and snippets.

@xofred

xofred/force_bot.rb

Last active Sep 1, 2020
Embed
What would you like to do?
Auto generate factory_bot model definition on legacy project
# Solve https://github.com/thoughtbot/factory_bot_rails/issues/63
# Original credit https://stackoverflow.com/a/50319158/2180787
# If you use Rails and see the following error:
# Could not find generator 'factory_bot:model'. Maybe you meant 'test_unit:model', 'active_record:model' or 'rspec:model'
# Run `rails generate --help` for more options.
#
# Make sure factory_bot_rails is in the Gemfile relative enviroment group, such as development, test
#
#group :development, :test do
# gem "factory_bot_rails", "~> 4.0"
#end
# If you use spring and see the following error:
# There is a version mismatch between the spring client (1.7.1) and the server (2.1.0).
# Restarting to resolve.
# Run `spring stop`, then retry.
# If you see the following error:
# Factory already registered: some_model (FactoryBot::DuplicateDefinitionError)
#
# Check the file in traceback (such as spec/factories/some_models.rb)
# And globally search the factory defined in that file (such as some_model).
# Then you might want to add that table to the @tables_to_ignore.
#
#@tables_to_ignore << 'cart_items'
#tables = ActiveRecord::Base.connection.tables.reject{|t| (@tables_to_ignore || []).include?(t)}
#
# Remove the duplicated file, then retry
@run_command = true
@force = false # override existing factory_bot file
@skip = true # skip existing factory_bot file
@spring = false # use spring to speed up rails loading (highly recommended)
@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_with_index do |table, index|
current = index + 1
begin
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
command << ' --skip' if @skip
command = 'spring ' + command if @spring
puts command
puts %x{#{command}} if @run_command
puts (1..20).to_a.map{}.join('-') << "progress: (#{current}/#{tables.size})\n\n"
rescue NameError # uninitialized constant SomeTableWithoutModelDefinition
puts $!.message
next
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment