Skip to content

Instantly share code, notes, and snippets.

@rails-hub
Created May 18, 2015 07:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rails-hub/23cd04e9a1d3c0d7c1f5 to your computer and use it in GitHub Desktop.
Save rails-hub/23cd04e9a1d3c0d7c1f5 to your computer and use it in GitHub Desktop.
require 'open-uri'
require 'csv'
class Import < ActiveRecord::Base
attr_reader :account
attr_reader :file
has_one :import_file, class_name: 'Attachment::ImportFile', as: :attachable
belongs_to :importable, polymorphic: true
accepts_nested_attributes_for :import_file
after_create :initialize_file_attributes
class AsyncJob
include SuckerPunch::Job
def perform(import)
import.process(import)
end
end
def enqueue_for_processing
AsyncJob.new.async.perform(self)
end
def process(import)
error_messages = []
# initialize processing attributes
import.update_attributes(row_processed_count: 0, complete: false, completed_at: nil)
# process file
members_hash = CSV.parse(open(import.import_file.asset.url).read, :headers => true)
members_hash.each_with_index do |row, index|
errors = process_row(row, import.column_map, import.importable)
error_messages << { index: index+1, message: errors } if errors
# update processing count
import.update_attributes(row_processed_count: index + 1) if index % 25 == 0
end
# set complete status
import.update_attributes(row_processed_count: members_hash.count, :complete => true, :completed_at => Time.now, row_error_count: error_messages.count, error_messages: error_messages)
end
private
def initialize_file_attributes
self.sample_rows = []
self.error_messages = []
# read file
file = CSV.parse(open(self.import_file.asset.url).read, headers: true)
# set header row
self.header_row = file.headers
self.row_count = file.count
# get sample rows
file.each_with_index do |row, index|
self.sample_rows << row.fields if index < 100
end
self.save!
end
private
def process_row(row, column_map, organization)
errors = nil
user = User.find_by_email(row[column_map['email']]) || User.create(first_name: row[column_map['first_name']], last_name: row[column_map['last_name']], email: row[column_map['email']])
errors = user.errors.full_messages if user.errors.count > 0
unless errors
unless row[column_map['tags']].blank?
row[column_map['tags']].split(',').each do |tag|
tag = Tag.where('lower(name) = ?', tag.downcase.squish).first
Tagging.create(taggable: user, tag: tag) if tag && !user.tags.map(&:id).include?(tag.id)
end
end
membership = Membership.create(member: user, organization: organization, role: row[column_map['role']])
errors = membership.errors.full_messages if membership.errors.count > 0
end
errors
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment