# Adapted from http://paulbarry.com/articles/2008/04/19/importing-data-with-rails require 'faster_csv' if Object.const_defined?('FasterCSV') module ScaffoldLogic class DataImport attr_reader :file, :fields, :row_map # Class Methods ================================================================================== def self.run(file) new(file).run end def self.save(upload) # create file path _path = File.join('tmp', upload['datafile'].original_filename) # write file File.open(_path, 'wb') { |f| f.write(upload['datafile'].read) } self.run(_path) end # Instance Methods =============================================================================== def initialize(file) @file = file raise 'You must specify a file' unless @file end def initialize_row! unless @fields_initialized initialize_fields! else initialize_row_map! process_row end end def create_from_row( model ) model.create(row_map) end def run @errors = [] @row_index = 1 FasterCSV.foreach(file, :col_sep => "\t", :row_sep => :auto) do |arg| @row = arg initialize_row! @row_index += 1 end @errors end def valid_row? @missing_fields = [] @required_fields.each do |field| @missing_fields << field if row_map[field].blank? end @missing_fields.empty? end private def initialize_fields! @fields = @row.map{ |f| f && f.strip.downcase.gsub(' ', '_').to_sym } @fields_initialized = true end def initialize_row_map! @row_map ||= {} @row_map.clear @row.each_with_index do |_c, _i| @row_map[fields[_i]] = _c && _c.strip end end end end