【问题标题】:Roo with rails4 giving undefined method `[]' for nil:NilClass带有 rails4 的 Roo 为 nil:NilClass 提供未定义的方法 `[]'
【发布时间】:2014-10-30 15:33:34
【问题描述】:

我正在尝试使用 Roo gem 将 CSV 和 Excel 文件导入到 rails 4 项目(经过验证),基于 http://railscasts.com/episodes/396-importing-csv-and-excel

我对 Rails4 而不是 Rails3 以及对 Roo 的更改做了一些更改,我的 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 错误发生在哪一行。请提供。
  • 我已经提供了。正如我所写,“它在header = spreadsheet.row(1) 上失败了”。那是load_imported_products的第4行,在调试puts之后我插入检查spreadsheet不是nil
  • .row(1) 不是方法[]。引发错误时,我要求提供完整的调用堆栈。 [] 可能来自 Roo - 您应该在调用堆栈中看到一行引用它。 .row(1) 只是触发错误的失败 API 调用。

标签: ruby-on-rails-4 roo-gem


【解决方案1】:

我遇到了同样的问题,好像是文件编码的问题,我用了这个代码,它已经修复了。

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

希望对你有帮助。

【讨论】:

  • 直到指定,默认编码是什么?
猜你喜欢
  • 2014-05-09
  • 1970-01-01
  • 1970-01-01
  • 2014-03-31
  • 2015-09-17
  • 2013-04-12
  • 2011-07-27
  • 2013-06-30
  • 1970-01-01
相关资源
最近更新 更多