Reputation: 1066
Model:
def self.import(csv_file)
line = 2
errors = []
CSV.foreach(csv_file, headers: true) do |row|
order = Order.find_or_initialize_by(projectid: row["projectid"], batch: row["batch"])
order.assign_attributes(row.to_hash)
if order.valid?
order.save!
else
errors << line
end
line += 1
end
return errors
end
here is the updated model code based on suggestions below; BIG thanks to Daiku and madcow thus far.
I think the reason that the record is not updating has to do with order.assign_attributes(row.to_hash) based on testing another and I did using the code above in the console, but with hard values.
I am trying to see what that code is doing now.
Upvotes: 0
Views: 1545
Reputation: 103
This should work. Update will attempt to save the item before updating it so it works with new records as well as found records.
def self.import(csv_file)
CSV.foreach(csv_file, headers: true) do |row|
order = Order.find_or_initialize_by(projectid: row["projectid"], batch: row["batch"])
if order.update(row.to_hash)
true
else
false
end
end
end
Upvotes: 1
Reputation: 1066
The answer was multifaceted and Madcow, Daiku, and Jake to an extent all had a piece of it.
The updated code in the original post now works fantastically. I had put an id column in the csv file that I was uploading thinking it needed to be there to work. It did not need to be there, in fact it needed to not be there.
{"id"=>nil, "projectid"=>"IADTST1RWKP01", "batch"=>"1", "ppiho"=>"2015-11-02", "needby"=>"2015-10-02", "quantity"=>"192", "manufacturer"=>"Delta", "model"=>"US Cords", "CAR"=>nil, "cfnum"=>nil, "prnum"=>nil, "ponum"=>nil, "status"=>"Quote Completed", "contact"=>"Mike Salafia", "notes"=>nil}
when that hash was presented to the order it rejected it because id was trying to be set to nil and it cannot be nil. However, I don't need id in the csv file to find the order and update it or create a new order as the projectid and batch can be used for find and the id is auto assigned.
So I needed a return, Daiku made me look at the hash harder, and Jake's code would also likely work.
Upvotes: 0
Reputation: 2633
Ideas:
Not sure exactly the context but if the use case includes updating the batch
for an existing project_id
, find_or_initialize_by
is not finding the existing item because it is looking for a record that has both the same project_id
and batch
.
Is projectid
a typo? Should it be project_id
?
Updated:
Also, you should have a return
inside of the foreach loop or it will abort early.
Upvotes: 0