问题描述
我正在尝试使用基于 http://railscasts.com/episodes/396-importing-csv-and-excel.
I'm trying to import CSV and Excel files into a rails 4 project (with validation) using the Roo gem, based on http://railscasts.com/episodes/396-importing-csv-and-excel.
我对 Rails4 而不是 Rails3 进行了一些更改,并对 Roo 进行了更改,现在我的 ProjectImporter 模型如下所示:
I've made some changes to account for Rails4 instead of Rails3 and for changes to Roo, and my ProjectImporter model now looks like:
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 =电子表格.row(1)
上失败,错误 undefined method '[]' for nil:NilClass
.我包含的额外的 puts
语句证实了 spreadsheet
本身不是 nil:它给出了 !!!电子表格:#
.但是,如果我尝试对其调用几乎所有预期的方法,例如 #last_row
,则会出现相同的未定义方法错误.
When I try to run an import (using test CSV data), it fails on header = spreadsheet.row(1)
with the error undefined method '[]' for nil:NilClass
. The extra puts
statement I've included confirms that spreadsheet
itself isn't nil: it gives !!! Spreadsheet: #<Roo::CSV:0x44c2c98>
. But if I try to call almost any of the expected methods on it, such as #last_row
, it gives me the same undefined method error.
那我做错了什么?
推荐答案
我也遇到了同样的问题,好像是文件编码的问题,我用了这段代码,解决了.
I had the same problem, it seems a problem about file enconding, I used this code and it was fixed.
def open_spreadsheet
case File.extname(file.original_filename)
when ".csv" then Roo::CSV.new(file.path, csv_options: {encoding: "iso-8859-1:utf-8"})
when ".xls" then Roo::Excel.new(file.path, nil, :ignore)
when ".xlsx" then Roo::Excelx.new(file.path, nil, :ignore)
else raise "Unknown file type: #{file.original_filename}"
end
end
希望对你有帮助.
这篇关于带有 rails4 的 Roo 为 nil:NilClass 提供未定义的方法 `[]'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!