0

I am trying to run a ruby script that parses a text file with album name, artist name, year on each line. It should then save a new record into a Rails model called Album.

(buildDB.rb)

fh = File.open('albums.txt')

while line = fh.gets
    if ( line =~ /^(.+)\~\s(.+) \(\'(\d\d)\)/ )
        a = Album.new
        a.name   = $1
        a.artist = $2
        a.year   = $3
        a.save
    end
end

I am running ruby buildDB.rb in terminal which produces the message

buildDb.rb:12:in '<main>': uninitialized constant Album (NameError)

This made me think that the script could not find the model. So I tried loading the rails environment by using

require "C:/ruby192/www/Project02/config/environment.rb"

at the top of the ruby script. The script will run without errors but nothing is committed to the sqlite database. I can also run find on the already existing Albums, it just seems I can't create new ones.

I am a rails noob so, there probably is a better way to do this (seeds.rb or a rake task maybe). Any help or a direction to look into would be greatly appreciated.

2 Answers 2

1

I would use a rake task:

task :create_albums => :environment do
  fh = File.open('albums.txt')

  while line = fh.gets
    if ( line =~ /^(.+)\~\s(.+) \(\'(\d\d)\)/ )
      a = Album.new
      a.name   = $1
      a.artist = $2
      a.year   = $3
      a.save!
    end
  end
  fh.close
end

I added a ! to the save method so that any errors will throw an exeception. Also, make sure you close your files.

Sign up to request clarification or add additional context in comments.

2 Comments

Actually the addition of the bang provided me with part of the problem. I had the model attribute year set on presence => true, but one of the returned years from the regex was empty. This threw an error on the script
Awesome! Got it working and learned a little about rake tasks. Thanks drummondj!
0

Rake task is the way ahead. I would use FasterCSV as it will handle some of the data import for you.

namespace :import do
  desc "Import from a csv file"
  task :album_csv, [:filename] => :environment do |task, args|

  lines = FasterCSV.read(args[:filename]) rescue nil
  if lines
    lines.slice!(0) # remove the CSV header if there is one
    puts "# Processing #{lines.count} records"
    lines.each do |line|
      a = Album.new
      a.name   = line[0]
      a.artist = line[1]
      a.year   = line[2]
      a.save!
    end
  end
end

You can then call your rake task as:

rake import:album_csv[filename]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.