Skip to content

Instantly share code, notes, and snippets.

@ianks
Last active August 29, 2015 14:25
Show Gist options
  • Save ianks/76edb070d5acc86f7711 to your computer and use it in GitHub Desktop.
Save ianks/76edb070d5acc86f7711 to your computer and use it in GitHub Desktop.
Generate FactoryGirl factories from models

I wanted to be able to auto-generate FactoryGirl factories from my database, so this task will do that, using Faker to give you fake data.

require 'erb'

task :factory_girl_translate, [:model] => [:environment] do |t, args|
  puts FactoryTemplate.new(model: args[:model]).render
end

class FactoryTemplate
  def initialize(model:)
    @klass = model.classify.constantize
    @model = model
    @attributes = @klass.attribute_names
  end

  def render
    ERB.new(template, nil, '-').result binding
  end

private

  def template
    <<-EOF
FactoryGirl.define do
  factory :<%= @model %>, class: <%= @klass.to_s -%> do
  <%- @attributes.each do |attr| -%>
    <%= attr -%> { <%= example_for attr -%> }
  <%- end -%>
  end
end
    EOF
  end

  def example_for(attr)
    case type_for attr
    when :integer  then 'Faker::Number.number'
    when :string   then 'Faker::Lorem.word'
    when :text     then 'Faker::Lorem.sentence'
    when :datetime then 'Faker::Date.backward(365)'
    when :json     then "{ test: 'json' }.to_json"
    else attr
    end
  end

  def type_for(attr)
    @klass.columns_hash[attr].type.to_sym
  end
end 

Then, $ rake factory_girl_translate[user] will generate a factory like this:

FactoryGirl.define do
  factory :user, class: User do
    id { Faker::Number.number }
    team_id { Faker::Number.number }
    email { Faker::Lorem.word }
    first_name { Faker::Lorem.word }
    last_name { Faker::Lorem.word }
    facebook_token { Faker::Lorem.word }
    facebook_uid { Faker::Lorem.word }
    password_digest { Faker::Lorem.word }
    access_token { Faker::Lorem.word }
    created_at { Faker::Date.backward(365) }
    updated_at { Faker::Date.backward(365) }
    metadata { { test: 'json' }.to_json }
    google_token { Faker::Lorem.word }
    google_refresh_token { Faker::Lorem.word }
    google_customer_id { Faker::Lorem.word }
    zip_code { Faker::Lorem.word }
  end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment