未定义的方法`fetch_value'对于nil:使用Roo时的NilClass

时间:2015-06-02 17:02:01

标签: ruby-on-rails roo

我正在尝试使用Roo将数据从Excel电子表格导入Rails应用程序中的表(data_points)。

我收到错误:

undefined method `fetch_value' for nil:NilClass

并且该错误在行引用了我的data_point.rb文件(参见下面的完整代码摘录):

data_point.save!

"应用程序跟踪"表示:

app/models/data_point.rb:29:in `block in import'
app/models/data_point.rb:19:in `import'
app/controllers/data_points_controller.rb:65:in `import'

我对此感到困惑,因为"发现所有"在我的整个应用程序中显示没有fetch_value的实例

以下是我的应用中的其他代码:

在我的模型中,data_point.rb:

class DataPoint < ActiveRecord::Base
attr_accessor :annual_income, :income_percentile, :years_education

def initialize(annual_income, income_percentile, years_education)
    @annual_income = annual_income
    @income_percentile = income_percentile
    @years_education = years_education
end

def self.import(file)
    spreadsheet = open_spreadsheet(file)
    header = spreadsheet.row(1)
    (2..11).each do |i| 
        annual_income = spreadsheet.cell(i, 'A')
        income_percentile = spreadsheet.cell(i, 'B')
        years_education = spreadsheet.cell(i, 'C')
        data_point = DataPoint.new(annual_income, income_percentile, years_education)
        data_point.save!
    end
end 

def self.open_spreadsheet(file)
    case File.extname(file.original_filename)
    when ".xlsx" then Roo::Excelx.new(file.path)
    else raise "Unknown file type: #{file.original_filename}"
    end
end
end

在我的控制器中,我添加了data_points_controller.rb,除了标准的rails框架:

def import
    DataPoint.import(params[:file])
    redirect_to root_url, notice: "Data points imported."
end

在我使用的Excel文件中,标题行的列名与上面提到的DataPoints的3个属性完全相同:annual_income,income_percentile,years_education

P.S。我已经看过RailsCast 396:导入CSV和Excel,并多次阅读评论。我认为我正在努力将示例代码转换为Rails 4和/或我对各个属性的分配(与RailsCast中使用的方法相比)。

提前感谢您的帮助!

5 个答案:

答案 0 :(得分:16)

在尝试将Active Record与旧数据库一起使用时,我也遇到了类似的错误。对我来说问题是因为我的数据库中的一列被命名为“class”,导致各种各样的事情失败。我重命名了遗留数据库中的列,一切正常。

故事的道德 - 检查任何保留字的列名。

答案 1 :(得分:8)

正如我们在评论中所发现的那样,你的非铁路练习似乎有一些剩菜。值得注意的是,覆盖的initialize方法和每个属性的attr_accessor。只需要删除它们(并将DataPoint.new()固定为正确的格式)。

答案 2 :(得分:5)

这是昨天遇到的问题,原因是我定义了一个名为class的数据库字段,这是Ruby语言的保留字。它引发了冲突。

答案 3 :(得分:0)

删除您的def initialize()方法

答案 4 :(得分:0)

如果您因某种原因被限制删除 initialize 方法,而不是删除它,您可以尝试添加一个 super 调用,如下所示:

def initialize(annual_income, income_percentile, years_education)
  super()

  @annual_income = annual_income
  @income_percentile = income_percentile
  @years_education = years_education
end

这为我解决了问题。

来源:

  • 有关 super 的更多信息,请参见 here