Rails 4 CSV上传到多个模型

时间:2015-07-09 20:55:05

标签: ruby-on-rails ruby-on-rails-4.1

我正在尝试上传包含两个不同模型的数据的csv文件:ProjectPurchaseOrder。我在模型之间使用has_many, :through关系。

我上传时遇到问题。我已将两个控制器中的共享属性列入白名单,并在两个模型中都包含accepts_nested_attributes

这是我在csv中阅读的代码。

  def self.import(file)
    CSV.foreach(file.path, headers: true) do |row|
      project_hash = row.to_hash
      project = Project.where(project_name: project_hash["project_number"]).first
      if project.present?
        project.first.update_attributes(project_hash)
      else
        Project.create! (project_hash)
      end
      purchase_order = PurchaseOrder.where(po_number: project_hash["po_number"]).first
      if purchase_order.present?
        PurchaseOrder.create!
      end

我有两个问题/问题。

  1. 我无法读取po_number属性。我收到此错误unknown attribute 'po_number' for Project

  2. 我不知道如何将创建的采购订单推送到项目哈希中,以便更新嵌套的属性值。

  3. 提前感谢能够提供帮助的任何人!

    ****更新 使用此方法,数据将保存到正确的表中。但是,不保存PurchaseOrder和Project之间的关联。有什么想法吗?

      def self.import(file)
        CSV.foreach(file.path, headers: true) do |row|
          project_hash = row.to_hash
          po_hash = {}
          po = PurchaseOrder.new
          project_hash.each { |k, v| po_hash[k] = project_hash.delete(k) if po.respond_to?(k) }    
    
          project = Project.where(project_name: project_hash["project_number"]).first
          if project.present?
            project.first.update_attributes(project_hash)
          else
            Project.create! (project_hash)
          end
    
          po = PurchaseOrder.where(po_number: po_hash["po_number"]).first
          if po.present?
            po.first.update_attributes(po_hash)
          else
            PurchaseOrder.create! (po_hash)
          end
        end
      end
    

1 个答案:

答案 0 :(得分:1)

这些行正在尝试使用哈希值中的所有值来更新/创建项目...

project.first.update_attributes(project_hash)
...
Project.create! (project_hash)

但很明显,一些哈希元素(例如“po_number”)在项目表中没有列。

您需要根据哪个元素属于哪个模型来拆分csv哈希元素...

e.g。

po_hash = {}
po = PurchaseOrder.new
project_hash.each { |k, v| po_hash[k] = project_hash.delete(k) if po.respond_to?(k) }

这将从project_hash中删除采购订单字段,并将其添加到po_hash,以便您可以使用正确的哈希值来更新正确的表格。

建立联系......

变化

Project.create!(project_hash)

进入

project = Project.create!(project_hash)

因此,无论项目是存在还是新创建,它都存储在变量“project”中。同样,做

po = PurchaseOrder.create!(po_hash) 

然后,在创建或更新采购订单后,您只需将po分配给项目......

project.purchase_orders << po