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

Helper methods

gnapse edited this page Sep 30, 2014 · 3 revisions

Complex importers make heavy use of callbacks and blocks in the column-mapping definitions. But code inside these blocks often escalates in complexity, and we need to extract some functionality into helper methods.

With active_importer, this is as simple as declaring instance methods in your importer class, and these will become available inside any callback or column-mapping block for you to invoke. Furthermore, you can access the row and model methods inside these helper methods too, since these are just other instance methods inherited by your class from ActiveImporter::Base.

Let's take, for instance, the example code below:

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

How about if we extract some functionality into a helper method?

class EmployeeImporter < ActiveImporter::Base
  imports Employee

  column 'Name', :full_name

  on :row_processing do
    model.manager = !!tag_list.delete('manager')
    model.tag_ids = tag_list.map { |tag| Tag.where(name: tag).first_or_create }
  end

  private

  def tag_list
    @tag_list ||= row['Tags'] ? row['Tags'].split(',').map(&:strip).map(&:downcase) : []
  end
end

With the new method tag_list we were able to simplify the logic inside the :row_processing callback. A few things are worth noting:

  • It's a good practice to declare helper methods as private. They are intended to be used only within the importer.
  • We can and should make use of instance variables whenever possible. In this case, the instance varialbe is preventing us to process and split the tags column twice.