require 'csv' class ImportController < ApplicationController def import puts "\n--- CSV DATA IMPORT ---" csv_data = CSV::Reader.parse(params[:file]) header = nil csv_data.each_with_index do |row, i| if (i == 0) header = row "*** Read column header." else puts "--- NEW ROW ---" fields = find_field_contents(header, row) customer = find_or_create_customer( fields[:customer_name] ) criterium = find_or_create_criterium( fields[:criterium_text], fields[:criterium_type], customer ) if customer create_text_module_if_does_not_exist( fields[:reference_type] || 'any', fields[:gender] || 'any', fields[:mark] || 'any', fields[:begins_paragraph] || 'no', fields[:ends_paragraph] || 'no', fields[:text_module_text], criterium ) if criterium end end flash[:notice] = 'Data successfully imported'.t redirect_to(:action => :index) rescue Exception => e flash[:error] = 'Error: Unable to process the file specified or no file specified.'.t redirect_to(:action => :index) end private def find_field_contents(header, row) fields = {} header.each_with_index do |column_name, i| if column_name.include?(' ') language = column_name.split(' ')[1] column_name = column_name.split(' ')[0] if fields[column_name.to_sym].nil? fields[column_name.to_sym] = {language.to_sym => row[i]} else fields[column_name.to_sym][language.to_sym] = row[i] end else fields[column_name.to_sym] = row[i] end end return fields end def find_or_create_customer(customer_name) if customer_name.blank? customer = find_or_create_default_customer else unless customer = Customer.find_by_name(customer_name) customer = Customer.create(:name => customer_name) unless customer_name.empty? puts "*** Created customer `#{customer_name}`." end end return customer end def find_or_create_criterium(criterium_texts, criterium_type, customer) criterium = nil criterium_texts.each do |language, criterium_text| if (criterium_translation = CriteriumTranslation.find_by_text( criterium_text, :include => :criterium, :conditions => ['criteria.customer_id = ?', customer.id] )) criterium = criterium_translation.criterium criterium_texts.delete(language) end end if !criterium criterium = Criterium.create( :customer_id => customer.id, :criterium_type_id => CriteriumType.find_by_name(criterium_type).id ) puts "*** Created new criterium (##{criterium_texts.inspect})." end empty_criterium_text = false criterium_texts.each do |language, criterium_text| if criterium_text.empty? empty_criterium_text = true else criterium.translations << CriteriumTranslation.new( :language_id => ReferenceLanguage.find_by_short(language.to_s).id, :text => criterium_text ) end end if empty_criterium_text criterium.destroy criterium = nil end return criterium end def create_text_module_if_does_not_exist(reference_type, gender, mark, begins_paragraph, ends_paragraph, text_module_texts, criterium) text_module_texts.each do |language, text_module_text| if (reference_type && gender && mark && text_module_text) conditions_text = 'text = ? AND criterium_id = ? AND language_id = ?' conditions_text << ((mark == 'any') ? ' AND mark_id IS ?' : ' AND mark_id = ?') conditions_text << ((gender == 'any') ? ' AND gender_id IS ?' : ' AND gender_id = ?') conditions_text << ((reference_type == 'any') ? ' AND reference_type_id IS ?' : ' AND reference_type_id = ?') text_modules = TextModule.find(:all, :conditions => [ conditions_text, text_module_text, criterium.id, ReferenceLanguage.find_by_short(language.to_s).id, ((mark == 'any') ? nil : RatingMark.find_by_name(mark).id), ((gender == 'any') ? nil : ReferenceGender.find_by_name(gender).id), ((reference_type == 'any') ? nil : ReferenceType.find_by_name(reference_type).id) ]) unless text_modules.any? begins_paragraph = false if (begins_paragraph == 'no') ends_paragraph = false if (ends_paragraph == 'no') begins_paragraph = true if (begins_paragraph == 'yes') ends_paragraph = true if (ends_paragraph == 'yes') criterium.text_modules << TextModule.new( :mark_id => ((mark == 'any') ? nil : RatingMark.find_by_name(mark).id), :language_id => ReferenceLanguage.find_by_short(language.to_s).id, :reference_type_id => ((reference_type == 'any') ? nil : ReferenceType.find_by_name(reference_type).id), :gender_id => ((gender == 'any') ? nil : ReferenceGender.find_by_name(gender).id), :text => text_module_text, :begins_paragraph => begins_paragraph, :ends_paragraph => ends_paragraph ) puts "*** Created text module `#{text_module_text}`." end end end end end