0

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!

Niels
  • 69
  • 6

3 Answers3

1

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']}"
Cody Caughlan
  • 32,456
  • 5
  • 63
  • 68
  • Thank Cody, using your approach I was able to find an additional post (http://stackoverflow.com/questions/3024010/create-or-update-method-in-rails) that helped me in finding the working syntax! – Niels Aug 18 '14 at 16:32
1

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).

pdobb
  • 17,688
  • 5
  • 59
  • 74
0
   product = Product.first_or_initialize(secundary_key: row['secundary_key'])
   product.update_attributes(row.to_hash.except('secundary_key'))
Niels
  • 69
  • 6