Create a gist now

Instantly share code, notes, and snippets.

import seed data from .csv or .yml for Rails 2.3.4+

Rails SeedImporter

  1. Put this code at #{Rails.root}/db/seeds.rb
  2. type rake db:setup

Limitation

It supports only `id' primary key.

# -*- mode: ruby; coding: utf-8 -*-
class SeedImporter
def initialize
@model = nil
@with_id = false
@dragonfly_fields = []
@paperclip_fields = []
end
def run
Dir.glob( File.join( seed_dir, '**/*.{yml,csv}' ) ).sort.each { |seed|
send( "import_#{File.extname( seed )[1..-1]}_seed", seed )
}
end
def seed_dir
ENV['SEED_DIR'] || File.dirname(__FILE__) + '/seeds'
end
def fcsv_opts
{ :headers => true,
:header_converters => :downcase }
end
def import_csv_seed( file )
init_model( file, '.csv' )
FasterCSV.table( file, fcsv_opts ) { |csv|
@with_id = csv.headers.include?( 'id' )
}
if ( @with_id )
_import_csv( file ) { |row| create_and_save_with_id( row.to_hash ) }
else
_import_csv( file ) { |row| create_and_save( row.to_hash ) }
end
end
def _import_csv( file, &block )
FasterCSV.open( file, fcsv_opts ).each { |csv| block.call( csv ) }
end
def import_yml_seed( file )
init_model( file, '.yml' )
YAML.load_file( file ).each_pair { |k, v|
if ( v.has_key?( 'id' ) )
create_and_save_with_id( v )
else
create_and_save( v )
end
}
end
def to_model( file, suffix )
File.basename( file, suffix ).sub( /\A[0-9]+(_\.)?/, '' ).classify
end
def init_model( file, suffix )
@model = Object.const_get( to_model( file, suffix ) )
init_file_fields
end
def create_and_save( data )
save( create( data ) )
end
def create_and_save_with_id( data )
record = create( data )
record['id'] = data['id']
save( record )
end
def create( data )
attach_file_when_need( data )
end
def attach_file_when_need( data )
record = @model.new( data )
if ( @dragonfly_fields.size > 0 )
@dragonfly_fields.each { |e|
col = e.to_s
file = data[e] || data[e.to_s]
path = File.join( seed_dir, file )
record.send( "#{col}=",
open( path ).read ) if file and File.exist?( path )
}
end
if ( @paperclip_fields.size > 0 )
@paperclip_fields.each { |e|
col = e.to_s
file = data[e] || data[e.to_s]
path = File.join( seed_dir, file )
record.send( "#{col}=",
open( path ) ) if file and File.exist?( path )
}
end
record
end
def save( record )
record.save!
end
def init_file_fields
if ( defined? ::Dragonfly )
@dragonfly_fields = @model.dragonfly_apps_for_attributes.keys if @model.dragonfly_apps_for_attributes
end
if ( defined? ::Paperclip )
@paperclip_fields = @model.attachment_definitions.keys if @model.attachment_definitions
end
end
end
SeedImporter.new.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment