Skip to content
This repository has been archived by the owner on Nov 23, 2021. It is now read-only.

Custom data processing

Ernesto Garcia edited this page Feb 23, 2014 · 3 revisions

Importers are most commonly designed by establishing a mapping between spreadsheet columns and model attributes. But sometimes this simple mapping approach is not enough. It it possible to find cases where we really need to do some custom and more complex processing of the incoming data before deciding how and where to store data into the model.

For these edge cases active_importer provides a "anything goes" block of code, where you have unrestricted access to the contents of the row being processed, and to the model object where the data needs to be stored. Let's dive in directly to an example:

class EmployeeImporter < ActiveImporter::Base
  imports Employee

  column 'Name', :full_name

  on :row_processing do
    if row['Tags'].present?
      tags = row['Tags'].split(',').map(&:strip).map(&:downcase)
      model.manager = !!tags.delete('manager')
      model.tag_ids = tags.map { |tag| Tag.where(name: tag).first_or_create }
    end
  end
end

First of all, note the references to the row and model methods. These are special methods provided by the importer.

  • The row method returns a hash containing the column headers as keys and the values for each of those columns in the current row.
  • The model method holds a reference to the model object on which to store the data from the current row. It is an instance of the model class declared in the importer using the imports clause (in this case it's an instance of the Employee class).

Also note that the processing inside this block is more complex than the average work you would normally do inside a column-mapping block. For starters, the tag column is optional. It may or may not be there. The processing that needs to be done to its data is more complex than usual. Plus, its contents affect other model attributes as well (the :manager attribute).

Helper methods

If logic inside this callback ever gets too complex, you may need to do some refactoring. In that case remember you can use helper methods to DRY-up your importer code.