我正在关注Import CSV Railscast并且它很直接。
问题是它只处理一个csv文件,该文件只包含1个文件中1个模型的信息。
说,我有一个CSV文件,我试图导入我的Listing
模型。在每行/列表上,它有一个名为Building
的列,其中值实际上是该列表的建筑属性的名称(即@listing.building.name
)。
如何在导入中处理这些案例?
这是Ryan在Railscast中获得的壁橱,在他的案例中位于Product
模型上:
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
product = find_by_id(row["id"]) || new
product.attributes = row.to_hash.slice(*accessible_attributes)
product.save!
end
end
所有发生的事情是他正在检查产品是否存在以及是否存在然后更新属性。如果没有,则创建一个新的。
在这种情况下不太确定如何处理关联...特别是考虑到在相关记录不存在的情况下需要发生的事情,需要在此过程中创建它。
回到之前的building.name
示例,如果没有Building.find_by_name(name)
,那么它应该创建一个新的建筑记录。
思想?
答案 0 :(得分:2)
试试这个
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
product = find_by_id(row["id"]) || new
product.attributes = row.to_hash.slice(*accessible_attributes)
product.save!
building = product.buildings.find_by_name(row['building_name'])
building ||= product.buildings.build
building.attributes = row.to_hash.slice(*build_accessible_attributes)
building.save!
end
end
更新:使用新的rails 3方法更新答案
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
product = where(id: row["id"])
.first_or_create!(row.to_hash.slice(*accessible_attributes))
product.buildings.where(name: row['building_name'])
.first_or_create!(row.to_hash.slice(*building_accessible_attributes))
end
end