我的模型如下:
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
排。
感谢任何帮助。
这里的问题是您的电子表格数据不包含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
列表。