21

I know this question has been asked a lot on this forum but I'm under a strict deadline and I need some help, so any advice is much appreciated. I'm new to Ruby on Rails so please keep that in mind when responding. I want to create a rake task that, when run, updates multiple tables in mysqlite db. This is a migration file that creates a new incident in my db. How do I create a rake task that will input all this info via a CSV file. Can someone PLEASE give me some help in writing the rake file from start to finish. Obviously you don't need to write every task for every string, just give me a few examples. And besides the actual rake file, do I need to add code to any other part of my app (I know thats a very general question, but if I do need to add code, I would appreciate a general description of where). I feel a little bit of guidance will go along way. If anyone needs any more information from me please just ask.

class CreateIncidents < ActiveRecord::Migration
  def self.up
    create_table :incidents do |t|
      t.datetime :incident_datetime
      t.string :location
      t.string :report_nr
      t.string :responsible_party
      t.string :area_resident
      t.string :street
      t.string :city
      t.string :state
      t.string :home_phone
      t.string :cell_phone
      t.string :insurance_carrier_name
      t.string :insurance_carrier_street
      t.string :insurance_carrier_city
      t.string :insurance_carrier_state
      t.string :insurance_carrier_phone
      t.string :insurance_carrier_contact
      t.string :policy_nr
      t.string :vin_nr
      t.string :license_nr
      t.string :vehicle_make
      t.string :vehicle_model
      t.string :vehicle_year


      t.timestamps
    end
  end

  def self.down
    drop_table :incidents
  end
end
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
RubyDude1012
  • 477
  • 1
  • 8
  • 14

5 Answers5

21

under your project folder in lib/task create a rake file say "import_incidents_csv.rake"

follow this Ruby on Rails - Import Data from a CSV file

in rake file have following code

require 'csv'
namespace :import_incidents_csv do
  task :create_incidents => :environment do
    "code from the link"  
  end
end 

You can call this task as "rake import_incidents_csv:create_incidents"

Community
  • 1
  • 1
Rubyman
  • 874
  • 6
  • 15
  • My issue is that I don't know the code to put in the rake file that properly creates the new incident without any errors. But thanks for the response. – RubyDude1012 Sep 17 '12 at 14:30
  • You will need to create a csv file with first row as column names of the incidents table. – Rubyman Sep 17 '12 at 14:37
  • This is the code I found on StackOverflow that I've tried to adapt to my app. I'm having trouble getting it formatted to read though...sorry desc "One line task description" task :import_csv do require 'csv' csv_text = File.read('c:/rails/thumb/incidents.csv') csv = CSV.parse(csv_text, :headers => true) csv.each do |row| row = row.to_hash.with_indifferent_access Incidents.create!(row.to_hash.symbolize_keys) end end – RubyDude1012 Sep 17 '12 at 15:04
  • The first error I got was undefined method 'with_indifferent_access'. So I removed that and now I'm getting uninitialized constant Object::Incidents. The csv file I'm importing is a modification to the incidents report I exported using SQLite Manager. I removed the all the previous incidents and typed in a dummy one. I exported it using comma separators and made sure it had the first row identified as column names. Am I even on the right track?? – RubyDude1012 Sep 17 '12 at 15:17
  • Thanks for the help Rubyman, but I still have a couple more questions (some newbie questions). Where you put "code from link" I added all the code I posted in my original question. I'm not sure if that what you meant or not. When I run the rake command you specified, it works without errors, but the incident isn't being added. I am not specifying anywhere in this process where the rake file should look for the csv file, which has to be the problem. Where do I put the csv file or where do i specify the path? Thanks – RubyDude1012 Sep 17 '12 at 15:53
  • Sorry Rubyman I misread your response. I made the adjustments and the IMPORT WORKED!!! Thanks so much for giving me a starting point to make my updates. You have no idea how much you helped me...I was freaking out a little if you couldn't tell. THANKS AGAIN!!! – RubyDude1012 Sep 17 '12 at 16:30
  • If this answer helped you, pls accept it, so I will get some reputation points.. :) – Rubyman Sep 18 '12 at 06:56
11

I worked on this for hours and hours one day. I finally got it to work by doing the following:

  1. Added a header in the first row to my csv file that reflected the attr_accessible in my model. In my case my model was attr_accessible :intro, :name and in my csv file the first line read name, intro.
  2. Created a custom rake file. I named mine import.rake and placed it in the lib/tasks folder. Place this code in that file:
#lib/tasks/import.rake
require 'csv'
desc "Imports a CSV file into an ActiveRecord table"
task :import, [:filename] => :environment do    
    CSV.foreach('myfile.csv', :headers => true) do |row|
      MyModel.create!(row.to_hash)
    end
end

Then type bundle exec rake import into the command line.

To get this to work I had quite SQLite Database Browser. I hope that helps someone!

tkanzakic
  • 5,499
  • 16
  • 34
  • 41
lflores
  • 3,770
  • 3
  • 19
  • 24
2

Here is an example CSV that I imported using rake db:seed. I wrote this into the seeds.rb file and put the CSV file into /public/seed_data/zip_code.csv. It's pretty self explanatory (i.e., the csv has three columns: code, long. and lat.

The code parses each line, extracts the pertinent data and assigns it to a local variable then writes it to a record. Hope it helps.

File.open("#{Rails.root}/public/seed_data/zip_code.csv") do |zip_codes|
  zip_codes.read.each_line do |zip_code|
    code, longitude, latitude = zip_code.chomp.split(",")
    #  to remove the quotes from the csv text:
    code.gsub!(/\A"|"\Z/, '')
    # to create each record in the database
    ZipCodeGeo.create!(:zip_code => code, :longitude => longitude, :latitude =>      latitude)             
  end
end
Angelo Chrysoulakis
  • 846
  • 2
  • 7
  • 21
0

You can read your csv file using CSV module of rails and can create records. Here is detailed help: Populate db using csv

RAJ
  • 9,697
  • 1
  • 33
  • 63
0

I've used this one in the past. It takes any type of model.

rake csv_model_import[bunnies.csv,Bunny]

Works like a charm.

desc "Imports a CSV file into an ActiveRecord table"
task :csv_model_import, :filename, :model, :needs => :environment do |task,args|
  lines = File.new(args[:filename]).readlines
  header = lines.shift.strip
  keys = header.split(',')
  lines.each do |line|
    params = {}
    values = line.strip.split(',')
    keys.each_with_index do |key,i|
      params[key] = values[i]
    end
    Module.const_get(args[:model]).create(params)
  end
end
ebilly
  • 33
  • 1
  • 4