我试图使用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