我試圖使用Roo gem基於http://railscasts.com/episodes/396-importing-csv-and-excel將CSV和Excel文件導入到rails 4項目(帶驗證)中。Roo with rails4給出了未定義的方法`[]'爲零:NilClass
我已經做了一些改動,以考慮Rails4代替Rails3中和改變小豆,我ProjectImporter模型現在看起來像:
class ProductImport
include ActiveModel::Model
attr_accessor :file
def initialize(attributes = {})
attributes.each { |name, value| send("#{name}=", value) }
end
def persisted?
false
end
def save
if imported_products.map(&:valid?).all?
imported_products.each(&:save!)
true
else
imported_products.each_with_index do |product, index|
product.errors.full_messages.each do |message|
errors.add :base, "Row #{index + 2}: #{message}"
end
end
false
end
end
def imported_products
@imported_products ||= load_imported_products
end
def load_imported_products
spreadsheet = open_spreadsheet
spreadsheet.default_sheet = spreadsheet.sheets.first
puts "!!! Spreadsheet: #{spreadsheet}"
header = spreadsheet.row(1)
(2..spreadsheet.last_row).map do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
product = Product.find_by(id: row['id']) || Product.new
product.attributes = row.to_hash.slice(*['name', 'released_on', 'price'])
product
end
end
def open_spreadsheet
case File.extname(file.original_filename)
when ".csv" then
Roo::CSV.new(file.path, nil)
when '.tsv' then
Roo::CSV.new(file.path, csv_options: { col_sep: "\t" })
when '.xls' then
Roo::Excel.new(file.path, nil, :ignore)
when '.xlsx' then
Roo::Excelx.new(file.path, nil, :ignore)
when '.ods' then
Roo::OpenOffice.new(file.path, nil, :ignore)
else
raise "Unknown file type #{file.original_filename}"
end
end
end
當我嘗試運行導入(使用測試CSV數據),它在header = spreadsheet.row(1)
上失敗,錯誤號爲undefined method '[]' for nil:NilClass
。我列出的額外puts
聲明確認spreadsheet
本身不是零:它給出!!! Spreadsheet: #<Roo::CSV:0x44c2c98>
。但是,如果我嘗試調用幾乎所有的預期方法,例如#last_row
,它會給我提供相同的未定義方法錯誤。
那麼我做錯了什麼?
它可能告訴你到底發生了什麼行'NilClass'錯誤。請提供。 – deefour 2014-10-30 16:33:59
我已經提供了。正如我寫的,「它在'header = spreadsheet.row(1)'」上失敗。這是'load_imported_products'的第4行,在插入調試'puts'後立即檢查'spreadsheet'不是'nil'。 – digitig 2014-11-04 09:15:56
'.row(1)'不是方法'[]'。發生錯誤時,我要求提供完整的調用堆棧。 '[]'可能來自Roo內部 - 您應該在調用堆棧中看到一行引用該行。 '.row(1)'就是您所做的失敗的API調用,會觸發錯誤。 – deefour 2014-11-04 13:10:34