0

我的模型如下:

class Horse < ActiveRecord::Base

  def self.import(file)
    allowed_attributes = ["name","place"]
    spreadsheet = open_spreadsheet(file)
    header = spreadsheet.row(1)
    (2..spreadsheet.last_row).each do |i|
      row = Hash[[header, spreadsheet.row(i)].transpose]
      horse = find_by_id(row["id"]) || new
      horse.attributes = row.to_hash.slice(*Horse.attribute_names())
      horse.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 Roo::Excelx.new(file.path, nil, :ignore)
    else raise "Unknown file type: #{file.original_filename}"
    end
  end
 end

当我将 Excel 文件上传到我的应用程序时,它会被解析并显示在表格中。我遇到的问题是,每次我上传 Excel 文件时,它都会创建一个新表并将其粘贴到前一个表的下方。

我希望能够上传带有更新数字的 Excel 表单,这些数字将添加到当前表中的数字中。

例如,如果我有一个 Excel 文件,其中包含:

Kane 1

然后我上传一个:

Kane 10

然后我希望表格显示:

Kane 11在行中。

感谢任何帮助表示赞赏。

4

1 回答 1

0

这里的问题是您的电子表格数据不包含id列。在RailsCast #369中添加此列以修改现有记录。从相应的ASCIIcast

修改现有记录

如果我们id的数据中有一个列可用于更新现有记录而不是添加新记录,那将很有用。这样我们可以下载一个 CSV 文件,修改其中的产品,然后上传它以一次更改多个产品。如果我们下载我们现有的产品,我们最终会得到这个 CSV 数据。

product.csv

id,name,released_on,price,created_at,updated_at
4,Acoustic Guitar,2012-12-26,1025.0,2012-12-29 18:23:40 UTC,2012-12-29 18:23:40 UTC
5,Agricola,2012-10-31,45.99,2012-12-29 18:23:40 UTC,2012-12-29 18:23:40 UTC
6,Christmas Music Album,2012-12-06,12.99,2012-12-29 20:55:29 UTC,2012-12-29 20:55:29 UTC
2,Red Shirt,2012-10-04,12.49,2012-12-29 18:23:40 UTC,2012-12-29 18:23:40 UTC
1,Settlers of Catan,2012-10-01,34.95,2012-12-29 18:23:40 UTC,2012-12-29 18:23:40 UTC
3,Technodrome,2012-12-22,27.99,2012-12-29 18:23:40 UTC,2012-12-29 18:23:40 UTC
7,Unicorn Action Figure,2012-12-06,5.85,2012-12-29 20:55:29 UTC,2012-12-29 20:55:29 UTC

为了让它发挥作用,我们需要改变产品的进口方式。我们不会为每一行数据创建一个产品,而是尝试根据id列中的值找到一个产品。如果没有找到匹配的记录,我们将使用find_by_id 以便返回 nil,在这种情况下,我们将创建一个新记录。接下来,我们将根据行中的数据设置产品的属性,因为这可能包括我们不想设置属性的属性,例如id我们将更新模型列表中列出的唯一属性 attr_accessible

于 2013-09-23T12:50:20.397 回答