#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]