Ruby скрипт для сохранения записей в Rails

#ruby-on-rails #ruby #activerecord #model #terminal

#ruby-on-rails #ruby #activerecord #Модель #терминал

Вопрос:

Я пытаюсь запустить скрипт Ruby, который анализирует текстовый файл с названием альбома, именем исполнителя, годом в каждой строке. Затем он должен сохранить новую запись в модели Rails под названием Album.

(buildDB.rb)

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

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

Я запускаю ruby buildDB.rb в терминале, который выдает сообщение

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

Это заставило меня подумать, что скрипт не смог найти модель. Итак, я попытался загрузить среду rails с помощью

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

в верхней части скрипта ruby. Скрипт будет выполняться без ошибок, но в базе данных sqlite ничего не зафиксировано. Я также могу запустить find для уже существующих альбомов, просто кажется, что я не могу создавать новые.

Я новичок в rails, поэтому, вероятно, есть лучший способ сделать это (seeds.rb или, возможно, задача rake). Любая помощь или направление для изучения были бы весьма признательны.

Ответ №1:

Я бы использовал задачу rake:

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

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

Я добавил! к методу сохранения, чтобы любые ошибки вызывали выполнение. Кроме того, убедитесь, что вы закрыли свои файлы.

Комментарии:

1. На самом деле добавление bang решило часть проблемы. У меня был установлен атрибут модели year в presence => true, но один из возвращенных лет из регулярного выражения был пустым. Это вызвало ошибку в скрипте

2. Потрясающе! Запустил его и немного узнал о задачах rake. Спасибо drummondj!

Ответ №2:

Задача Rake — это путь вперед. Я бы использовал FasterCSV, поскольку он будет обрабатывать часть импорта данных для вас.

 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
  

Затем вы можете вызвать свою задачу rake как:

 rake import:album_csv[filename]