Skip to content

Instantly share code, notes, and snippets.

@cooljl31
Forked from kurbmedia/factories.rake
Created September 13, 2017 12:15
Show Gist options
  • Save cooljl31/defa1e988ea08ec2c1b6f45638a74c0d to your computer and use it in GitHub Desktop.
Save cooljl31/defa1e988ea08ec2c1b6f45638a74c0d to your computer and use it in GitHub Desktop.
Generates FactoryGirl factories.rb from the database tables/columns
namespace :factories do
task :generate => :environment do
# Make a new factory file, moving the old one to factories_old.rb if one exists.
factory_file = "#{Rails.root}/spec/factories"
FileUtils.mv("#{factory_file}.rb", "#{factory_file}_old.rb") if File.exists?("#{factory_file}.rb")
fixture_file = File.open("#{factory_file}.rb", 'w') do |file|
# Capture all db tables, creating factories out of them.
model_names = ActiveRecord::Base.connection.tables.reject{ |table| table.match(/(schema|delayed)/i) }.collect{ |table| table }
model_names.each do |model|
# Find all of the columns in this table.
klass = model.classify.constantize
columns = klass.columns.reject{ |col| col.name.match(/(id|created_at|updated_at|type)/i) }
# Stub the factory with all of the columns, and add some fake values.
# Then write data to the file
#
file.write("Factory.define(:#{model.singularize}) do |#{model[0].downcase}|\n")
mock_values(model, columns).each{ |val| file.write("#{val}\n") }
file.write("end\n\n")
end
end
end
end
def mock_values(table_name, columns)
# Find the longest column name to format the strings
#
strlen = columns.map{ |col| col.name.length }.max
columns.inject([]) do |arr, col|
method_s = "#{table_name.to_s[0]}.#{col.name}"
mock_val = send("mock_#{col.type.to_s}_types", col.name)
arr.push(" #{method_s} ".concat((" " * (strlen - col.name.length))).concat(mock_val))
end
end
def mock_string_types(cname)
string_val =
if cname.match(/email/i); "[email protected]";
elsif cname.match(/first_name/i); "Test";
elsif cname.match(/last_name/i); "McTesterson";
elsif cname.downcase == "address"; "1234 Somewhere St";
elsif cname.downcase == "city"; "Richmond";
elsif cname.downcase == "state"; "Virginia";
elsif cname.match(/zip/i) or cname.match(/zip_code/i); "23219";
else ""
end
return "\"#{string_val}\""
end
def mock_integer_types(cname)
return '1'
end
def mock_decimal_types(cname)
return '1.0'
end
def mock_boolean_types(cname)
return "true"
end
def mock_datetime_types(cname)
return "DateTime.now"
end
def mock_date_types(cname)
return "Date.today"
end
def mock_time_types(cname)
return "Time.now"
end
def mock_text_types(cname)
return "\"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\""
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment