- Put this code at #{Rails.root}/db/seeds.rb
- type
rake db:setup
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 ) | |
begin | |
record.save! | |
rescue => e | |
p record | |
p record.errors | |
raise e | |
end | |
end | |
def init_file_fields | |
if ( defined? ::Dragonfly ) | |
@dragonfly_fields = | |
if @model.respond_to? :dragonfly_apps_for_attributes # v0.8 | |
@model.dragonfly_apps_for_attributes.keys | |
elsif @model.respond_to? :dragonfly_attachment_classes # v0.9 | |
@model.dragonfly_attachment_classes.map { |c| | |
c.attribute | |
} | |
end | |
end | |
if ( defined? ::Paperclip ) | |
@paperclip_fields = @model.attachment_definitions.keys if @model.attachment_definitions | |
end | |
end | |
end | |
SeedImporter.new.run |
You can use fast_seeder(https://github.com/greyblake/fast_seeder) as well. It support number of DB adapters.