Sometimes there is a need to seed your database with real data and when that happens it is usually exported CSV file from somewhere else. What to do, what to do... I'll tell you what to do!

There are many approaches to this and this is only one, it may not be best one but definitely working one.

I chose to do this as rake task since it is usually needed only once and then again while in development there may be times when you need to run it more than once - if you happen to clear your database like I do many times in development cycle :)

This is not mentioned to be about how to do rake tasks but for some reason, it came out that way, a bit.

So, let's get our hands in the sand!

The rake task

I decided to name my small task as Seed from CSV so I created a file called seed_from_csv.rake under lib/tasks. Notice, the file extension should be rake not rb.

To get basics in place on this task file, start with:

namespace :csv_import do
  desc "Seed data.csv from db/csv_seeds to database table"

Like the description says, your data.csv will be placed on db/csv_seeds folder. It is good to keep your files in proper places or otherwise things will get messy later on your projects.

Go on with:

task mydata: :environment do
    require "csv"
    data = CSV.read("db/csv_seeds/data.csv")

    data.each do |line|
      MyModel.create(name: line[0])
    end
    puts("File imported")
  end

In the first line, we name our task as mydata. And when you write out rake --tasks you can see

rake csv_import:mydata # Seed data.csv from db/csv_seeds to database table

Next we add csv-library to go and start the actual job with CSV.read. This is easier than you expected.

Once we have content in data we can loop thru it line by line and create corresponding rows to the database. This example expects you to have a model called MyModel with corresponding table in the database having a column name.

Our example data.csv could be something like:

Mika,Hero Street,Hero City
Pentti,Super Street,Super City
Mark,Wonder Street,Wonder City
Spencer,Aqua Street,Aqua City

Our rake task handles only first column, name. If you want to read also street column you need to expand your create-command little:

MyModel.create(name: line[0], address: [1])

That's it! Simple, wasn't it?