通过CSV导入到Rails时的多个记录

时间:2015-06-16 08:48:09

标签: ruby-on-rails ruby csv import-from-excel

我正在通过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_title hotel_location country_code contact_name

2 个答案:

答案 0 :(得分:0)

如果酒店模型中不存在该字段,则无法分配该字段。这会引起错误

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

您必须将其从允许的属性中删除,并在行中存在值时显式撰写联系人。

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

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

答案 1 :(得分:0)

您可以设置setter方法contact_name=来执行此功能。

#in Hotel

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

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