Reputation: 69
I am importing a CSV file using 'csv'. Import is working as expected, but I would like to update existing records, based on a secondary key field.
I am using the following code:
CSV.foreach(path, :headers => true) do |row|
if(Product.exists?(secondary_key: row['secondary_key']))
#Update goes here
else
Product.create!(row.to_hash)
end
I have tried (among others):
product = Product.where(:secondary_key => row['secondary_key'])
Product.update(product, row.to_hash)
Now that trial-and-error is not bringing me anywhere, I would appreciate your help!
Upvotes: 0
Views: 112
Reputation: 69
product = Product.first_or_initialize(secundary_key: row['secundary_key'])
product.update_attributes(row.to_hash.except('secundary_key'))
Upvotes: 0
Reputation: 18037
How about using find_or_initialize_by:
CSV.foreach(path, :headers => true) do |row|
product = Product.find_or_initialize_by(secondary_key: row['secondary_key'])
product.update(row.to_hash.except('secondary_key'))
end
First we either find the existing product by the secondary_key or we initialize a new one with secondary_key. Then, in either case, we update all product attributes from the row values (excluding the secondary_key value since that's already set).
Upvotes: 1
Reputation: 32748
You can issue an update statement using this syntax:
Product.where(secondary_key: row['secondary_key']).update_all(:foo => "bar")
This will generate a query like
UPDATE products SET foo = 'bar' WHERE secondary_key = "#{row['secondary_key']}"
Upvotes: 1