How to refactor this importer to handle validation errors?
It can be as simple as :

  def initialize(path)
    @path = path 
    @imported = []
    @errors = []
  end

  def extract sheet_name
    @file.default_sheet = sheet_name

    header = file.row 1
    2.upto(file.last_row) do |i|
      row = Hash[[header, file.row(i)].transpose]
      # row.delete "id"
      model = sheet_name.classify.constantize

      # this is the part that gets the job done.
      object = model.new(row)
      if object.save
        @imported &lt;&lt; object
      else
        @rejected &lt;&lt; object
      end

    end
  end


... this way you can iterate through @imported or @rejected at the end of the import process (to display errors, or perform additional tasks).

This code can also easily be adapted to only catch exceptions : 

  def extract sheet_name
    @file.default_sheet = sheet_name

    header = file.row 1
    2.upto(file.last_row) do |i|
      row = Hash[[header, file.row(i)].transpose]
      # row.delete "id"
      object = sheet_name.classify.constantize
      object.create!(row)
    end
  rescue ActiveRecord::RecordNotUnique, ActiveRecord::RecordInvalid =&gt; error
    # rejected record for these errors can be accessed with :
    error.record
    # to resume processing, just :
    error.continue
  end