Skip to content

Instantly share code, notes, and snippets.

@matthutchinson
Created May 10, 2012 16:59

Revisions

  1. matthutchinson created this gist May 10, 2012.
    105 changes: 105 additions & 0 deletions fakeout.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,105 @@
    # place this in lib/fakeout.rb

    require 'ffaker'

    module Fakeout
    class Builder

    FAKEABLE = %w(User Product)

    attr_accessor :report

    def initialize
    self.report = Reporter.new
    clean!
    end

    # create users (can be admins)
    def users(count = 1, options = {}, is_admin = false)
    1.upto(count) do
    user = User.new({ :email => random_unique_email,
    :password => 'Testpass',
    :password_confirmation => 'Testpass' }.merge(options))
    user.save
    if is_admin
    user.update_attribute(:is_admin, true)
    self.report.increment(:admins, 1)
    end
    end

    self.report.increment(:users, count)
    end

    # create products (can be free)
    def products(count = 1, options = {})
    1.upto(count) do
    attributes = { :name => Faker::Company.catch_phrase,
    :price => 20+Random.rand(11),
    :description => Faker::Lorem.paragraph(2) }.merge(options)
    product = Product.new(attributes)
    product.name = "Free #{product.name}" if product.free?
    product.save
    end
    self.report.increment(:products, count)
    end

    # cleans all faked data away
    def clean!
    FAKEABLE.map(&:constantize).map(&:destroy_all)
    end


    private

    def pick_random(model)
    ids = ActiveRecord::Base.connection.select_all("SELECT id FROM #{model.to_s.tableize}")
    model.find(ids[rand(ids.length)]['id'].to_i) if ids
    end

    def random_unique_email
    Faker::Internet.email.gsub('@', "+#{User.count}@")
    end
    end


    class Reporter < Hash
    def initialize
    super(0)
    end

    def increment(fakeable, number = 1)
    self[fakeable.to_sym] ||= 0
    self[fakeable.to_sym] += number
    end

    def to_s
    report = ""
    each do |fakeable, count|
    report << "#{fakeable.to_s.classify.pluralize} (#{count})\n" if count > 0
    end
    report
    end
    end
    end


    # Now the rake task
    # place this in lib/tasks/fake.rake

    require 'fakeout'

    desc "Fakeout data"
    task :fake => :environment do
    faker = Fakeout::Builder.new

    # fake users
    faker.users(9)
    faker.users(1, { :email => '[email protected]' }, true)

    # fake products
    faker.products(12)
    faker.products(4, { :price => 0 })

    # report
    puts "Faked!\n#{faker.report}"
    end