Rails 4 CSV is loaded into multiple models

I am trying to load a csv file that has data that belongs to two different models: Project

and PurchaseOrder

. I am using communication has_many, :through

between models.

I have problems downloading. I have included common attributes in both controllers and included accepts_nested_attributes

in both models.

Here's my code to read in 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

      

I have two questions / problems.

  • I cannot read the attribute po_number

    . I am getting this error unknown attribute 'po_number' for Project

    .

  • I don't know how to push the generated purchase order to the project hash so that it updates the value of the attached attribute.

Thanks in advance to everyone who can help!

**** Update With this method, the data is stored in the correct tables. However, the link between PurchaseOrder and Project is not preserved. Any thoughts?

  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

      

+3


source to share


1 answer


These lines are trying to update / build the project using all the values ​​in the hash ...

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

      

But obviously some hash items (eg "po_number") do not have columns in the projects table.

You need to split the csv hash elements based on which elements belong to which model ...

eg.

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

      

This will remove the PO fields from project_hash

and add them to po_hash

so you can use the correct hash to update the correct table.

To establish an association ...



change

Project.create!(project_hash)

      

in

project = Project.create!(project_hash)

      

so whether a project exists or is created, it is stored in the "project" variable. Similarly, do

po = PurchaseOrder.create!(po_hash) 

      

Then after you've created or updated the PO, you can simply assign po to the project ...

project.purchase_orders << po

      

+1


source







All Articles