未定义的局部变量或方法错误Rails 4.2.6

时间:2016-08-12 10:37:06

标签: ruby-on-rails ruby csv

我一直在引用RailsCasts #396来导入来自csv,xls,xlas文件的数据。根据railscast(Rails 3.2.9),导入方法是

def self.import(file)
  spreadsheet = open_spreadsheet(file)
  header = spreadsheet.row(1)
  (2..spreadsheet.last_row).each do |i|
    row = Hash[[header, spreadsheet.row(i)].transpose]
    product = find_by_id(row["id"]) || new
    product.attributes = row.to_hash.slice(*accessible_attributes)
    product.save!
  end
end

def self.open_spreadsheet(file)
  case File.extname(file.original_filename)
  when ".csv" then Csv.new(file.path, nil, :ignore)
  when ".xls" then Excel.new(file.path, nil, :ignore)
  when ".xlsx" then Excelx.new(file.path, nil, :ignore)
  else raise "Unknown file type: #{file.original_filename}"
  end
end

但是由于Rails 4x实现了强大的params,我得到了undefined local variable or method 'accessible_attributes'错误 所以我抬起头来找到这个stackoverflow问题Rails 4 how to call accessible_attributes from Model,根据我试过的答案

def attr_names
  [user_id, last_name, first_name, last_name_kana, first_name_kana, created_at,created_by, updated_at, updated_by, del_flag]
end

def self.import(file)
  spreadsheet = open_spreadsheet(file)
  header = spreadsheet.row(1)
  (2..spreadsheet.last_row).each do |i|
    row = Hash[[header, spreadsheet.row(i)].transpose]
    user = find_by(user_id: row["user_id"]) || new
    user.attributes = row.to_hash.slice(*attr_names)
    user.save!
  end
end

def self.open_spreadsheet(file)
  case File.extname(file.original_filename)
  when ".csv" then Roo::CSV.new(file.path, csv_options: {encoding: "SJIS"})
  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 

仍然得到相同的错误,只有这次是undefined local variable or method 'attr_names'。提前致谢

2 个答案:

答案 0 :(得分:1)

在模特身上,你应该成为self.attr_names。或者,你所有的方法都是自我,你可以扩展自我,如下:

extend self

def attr_names
  [user_id, last_name, first_name, last_name_kana, first_name_kana, created_at,created_by, updated_at, updated_by, del_flag]
end

def import(file)
  spreadsheet = open_spreadsheet(file)
  header = spreadsheet.row(1)
  (2..spreadsheet.last_row).each do |i|
    row = Hash[[header, spreadsheet.row(i)].transpose]
    user = find_by(user_id: row["user_id"]) || new
    user.attributes = row.to_hash.slice(*attr_names)
    user.save!
  end
end

def open_spreadsheet(file)
  case File.extname(file.original_filename)
  when ".csv" then Roo::CSV.new(file.path, csv_options: {encoding: "SJIS"})
  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

答案 1 :(得分:0)

试试这个

user.attributes = row.to_hash.slice(*column_names)