I have an Order/LineItem type application which inserts an Order and its associated Line Items into a database. After the order is created (after_create) I then call a function which updates a totals field in the Order table. However, when this runs it also runs an update query on all the line items, and because a paper_trail is active for :update, it causes new versions to be inserted too. The problem is, there can be hundreds of line items (the largest so far was 872), so obviously this isn't very optimised and because of the paper trail, we get unnecessary versions.
I've looked at the :touch symbol but this only seems to work child > parent and not parent > child.
Is there a way to stop the updates from being fired on the line items when their parent is updated?
Here are the condensed controller/models.
OrdersController:
class OrdersController < ApplicationController
def create
@order = Order.new(order_params)
if @order.save
render :json => @order, :serializer => ::OrderSerializer
end
end
Order Model:
class Order < ActiveRecord::Base
has_paper_trail
belongs_to :customer
has_many :line_items, :dependent => :destroy
after_create :update_total_quantities
accepts_nested_attributes_for :line_items
def update_total_quantities
update_attributes({:total_quantity => calculated_total_quantity})
end
end
LineItem model:
class LineItem < ActiveRecord::Base
has_paper_trail :on => [:update, :destroy]
belongs_to :order
end
Example of the problem from the logs:
INSERT INTO "line_items" ("colour", "created_at", "order_id", "price", "product_id", "quantity", "size", "updated_at", "variant_id") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING "id"[0m [["colour", 2], ["created_at", Wed, 08 Jan 2014 11:47:38 UTC +00:00], ["order_id", 1216], ["price", 77.0], ["product_id", 241702], ["quantity", 1], ["size", "18"], ["updated_at", Wed, 08 Jan 2014 11:47:38 UTC+00:00], ["variant_id", "241702_2_18"]
INSERT INTO "line_items" ("colour", "created_at", "order_id", "price", "product_id", "quantity", "size", "updated_at", "variant_id") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING "id" [["colour", 106], ["created_at", Wed, 08 Jan 2014 11:47:38 UTC +00:00], ["order_id", 1216], ["price", 20.0], ["product_id", 2753], ["quantity", 1], ["size", "18"], ["updated_at", Wed, 08 Jan 2014 11:47:38 UTC +00:00], ["variant_id", "2753_106_18"]
UPDATE "orders" SET "total_quantity" = $1, "updated_at" = $2 WHERE "orders"."id" = 1216 [["total_quantity", 878], ["updated_at", Wed, 08 Jan 2014 11:47:40 UTC +00:00]
UPDATE "line_items" SET "created_at" = $1, "updated_at" = $2 WHERE "line_items"."id" = 108533 [["created_at", Wed, 08 Jan 2014 11:47:38 UTC +00:00], ["updated_at", Wed, 08 Jan 2014 11:47:38 UTC +00:00]
UPDATE "line_items" SET "created_at" = $1, "updated_at" = $2 WHERE "line_items"."id" = 108526[0m [["created_at", Wed, 08 Jan 2014 11:47:38 UTC +00:00], ["updated_at", Wed, 08 Jan 2014 11:47:38 UTC +00:00