User input in a rake task

12 Jun 2013

Earlier this week I was pair programming with Obie, and we wanted to transfer a bunch of data from one service provider into another.

As we talked through the problem, we started working through a rake task to get the job done.

We eventually reached a point where it would’ve been helpful to be able to override some of the data that was provided by Provider A, so that we could ensure consistency amongst all the data.

At that point I suggested we use ‘gets’ in the terminal, but wondered aloud whether you could do that in a rake task.

To which Obie replied, “It’s all Ruby.”

It’s all Ruby indeed, because that’s exactly what we did.

Below I’ll create a simple rake task to illustrate the concept.

The following grabs event data from Provider A and transfers it to a mailing list at Provider B:

desc "It's all Ruby - 'gets' in a rake task"
task :scrub_and_transfer_event_data => :environment do
  # Setup a client with Provider A
  client = ProviderAClient.new(app_key: 'APP_KEY', user_key: 'USER_KEY')
  # Grab events data and map it to a new array of the same name
  events = client.user_list_events["events"].map {|e| e["event"]}

  # Now iterate through the data
  events.each do |event|
    puts "Processing #{event["title"]}"
    puts "----"
    puts event.inspect
    puts "----"

    # Figure out the correct location
    if event["venue"]
      default_location = "#{event['venue']['city']}, #{event['venue']['region']}"
    end

    # If the default location works, just hit enter and let the data keep processing
    # Otherwise, change the location name to your liking
    print "Enter location: [#{default_location}] "
    location_name = STDIN.gets.strip
    if location_name.blank?
      location_name = default_location
    end

    attendees = client.event_list_attendees(id: event["id"])["attendees"].map {|a| a["attendee"]}
    attendees.each do |attendee|
      puts "Adding #{attendee["first_name"]} #{attendee["last_name"]}"
      ProviderB::API.listSubscribe(
        id: MASTER_LIST_ID,
        email_address: attendee["email"],
        first_name: attendee["first_name"],
        last_name: attendee["last_name"],
        location: location_name,
        update_existing: true
      )
    end
  end
end

Enjoy!