0

In our Rails 3.2.13 app we need to query an API for Order data which has many associciated objects, and then store it in our database. Some records may already exist, so if they exist we want to update, if new then we want to create. We are importing thousands of records at a time.

I've been looking into the activerecord-import gem to help performance optimize this using the import method, and came up with the below code:

def add_details(order, tax_lines)
  tax_lines.each do |shopify_tax_line|
    taxlines_updated << Taxline.where(:order_id => order.id).first_or_initialize(
      :price => tax_line.price,
      :rate => tax_line.rate,
      :title => tax_line.title)
  end
  Taxline.import taxlines_updated, :validate => false
end

The problem is, if the record already exists then it is not updated, it only updates the attributes if the record is new.

How can I get this to work like: "if found -> update attributes" or "if not found -> new" on each record?

Many thanks!

4

3 回答 3

0

:synchronize选项可能有效

 def add_details(order, tax_lines)
      taxlines_updated = []
      tax_lines.each do |shopify_tax_line|
        taxlines_updated << Taxline.where(:order_id => order.id).first_or_initialize(
               :price => tax_line.price,
               :rate => tax_line.rate,
                :title => tax_line.title)
      end
      Taxline.import taxlines_updated, :validate => false, :synchronize => taxlines_updated
  end

对于 gem文档

    # * +synchronize+ - an array of ActiveRecord instances for the model
    # that you are currently importing data into. This synchronizes
    # existing model instances in memory with updates from the import.
于 2013-09-21T19:28:07.523 回答
0

是的。first_or_initialize 就是这样工作的。在 first_or_initialize 之后尝试 update_attributes。

Taxline.where(:order_id => order.id).first_or_initialize.update_attributes!( :price => tax_line.price, :rate => tax_line.rate, :title => tax_line.title)

于 2013-09-21T05:17:41.600 回答
0

这是我们最终使用的代码,可能不是最有效的,但它有效:

def add_details(shopify_orders)
    tax_lines = []
    shopify_orders.each do |shopify_order|
      shopify_order.tax_lines.each do |shopify_tax_line|
        tax_line = Taxline.where(:order_id => shopify_order.id).first_or_initialize
        tax_line.price = shopify_tax_line.price
        tax_line.rate = shopify_tax_line.rate
        tax_line.title = shopify_tax_line.title
        tax_lines << tax_line
      end
    end
    TaxLine.import tax_lines, :validate => false
end
于 2013-09-24T07:13:40.097 回答