通过 CSV 导入 Rails 时的多条记录

Posted

技术标签:

【中文标题】通过 CSV 导入 Rails 时的多条记录【英文标题】:Multiple Records when Importing to Rails via CSV 【发布时间】:2015-06-16 08:48:08 【问题描述】:

我正在通过 CSV 将一些数据导入我的 Rails 应用程序。导入工作正常,但是当我尝试将 contact_name 插入接受的属性时,出现错误:

酒店的未知属性“contact_name”

此字段不属于酒店,但如果它存在于电子表格中,我需要在导入期间创建一个新联系人并将其分配给该酒店。

 def self.import(file)

  allowed_attributes = [ "id", "status", "rooms", "country_code", "user_id", "hotel_title","hotel_location", "telephone", "email", "contract_date", "print_date", "created_at","updated_at"]
  spreadsheet = open_spreadsheet(file)
  header = spreadsheet.row(1)
  (2..spreadsheet.last_row).each do |i|

    row = Hash[[header, spreadsheet.row(i)].transpose]
    hotel = find_by_id(row["id"]) || new
    hotel.attributes = row.to_hash.select  |k,v| allowed_attributes.include? k 

    # ASSIGNING VARIABLES
    hotel_name = row["hotel_title"]

    hotel.map = Map.create(:hotel_id => row["id"], :status => 0, :title => "Map Publication for #hotel_name")
    hotel.app = App.create(:hotel_id => row["id"], :status => 0, :title => "Bespoke App for #hotel_name")
    hotel.save!
  end
end

为简单起见,我的 CSV 目前有 4 列。 hotel_titlehotel_locationcountry_codecontact_name

【问题讨论】:

ContactHotel是什么关系? 【参考方案1】:

如果酒店模型中不存在该字段,则无法分配它。这里会报错

hotel.attributes = row.to_hash.select  |k,v| allowed_attributes.include? k 

您必须将其从允许的属性中删除,并且如果该值存在于行中,则显式组合联系人。

if row.to_hash["contact_name"]
  hotel.contact = Contact.new(...)
end

上面的示例假设您有一个与Hotel 关联的Contact 模型。

【讨论】:

谢谢,但我现在看到了另一个错误。 (未定义的方法`contact=')我已经更新了我的原始消息以显示相关代码。 您应该创建一个不同的问题。现在以前的答案将变得毫无用处。 我明白了。我现在已经删除了,但你有什么想法吗?【参考方案2】:

您可以创建一个 setter 方法 contact_name= 来执行此功能。

#in Hotel

def contact_name=(name)
  contact = self.contacts.find_by_name(name) || self.contacts.build(:name => name)
end

因为您正在做build,直到在更新结束时保存酒店之前不会创建任何内容,此时联系人(如果已建立)也将被保存。

【讨论】:

以上是关于通过 CSV 导入 Rails 时的多条记录的主要内容,如果未能解决你的问题,请参考以下文章

Rails 5:在连接表记录上保存记录时的 STI 空键

在一次提交中更新多条记录? - 导轨 3

如何在oracle数据表中一次性插入多条记录?

在rails迭代CSV,记录错误但不停止循环

Ruby-on-Rails 3.2:导出包含大型数据集(100,000 条记录)的 CSV

问题:使用 phpMyAdmin Works 导入 csv,Php 脚本以不同方式处理 csv 导入