I’m trying to run a simple loop that increments an attribute in a database table, and isn’t incrementing as expected. Imagine that our application is a daily deals site. I’m using Rails 3.0.1, for the record.
class Deal
has_many :orders
end
class Order
belongs_to :deal
end
An Order also has an attribute “quantity” – for example of someone buys a few of the same thing.
if someone buys a bunch of orders in a shopping cart, we want to tally the total in each deal to track how many we sold in each deal.
@new_orders.each do |order|
order.deal.update_attribute(:order_count, order.deal.order_count + order.quantity)
end
Firstly, ignore the fact that there may be a better way to write this. This is a contrived example in order to get to my point.
Now, imagine that our current case is where someone bought 3 orders of the same deal in the shopping cart (for no good reason – this example is somewhat contrived). And let’s say each order had a quantity of 1.
I would have expected, at the end of the loop, the deal’s quantity to be 3. But when I run this code, whether in tests, on the browser, or in the console, I get 1.
It seems as if in each iteration of the loop, when it pulls “order.deal” – since each order happens to belong to the same deal, it’s pulling the deal from a cache. So let’s say before this loop began, the deal’s order_count was 0, each time it pulls a cached copy of the deal which has an order_count of 0.
Is this the expected behavior? Is there a way to turn off this type of caching? What’s even stranger is that a colleague of mine tried to run a similar loop in his project and got the expected total. Or am I missing something entirely?
Thanks for your help!
You aren’t saving the record. After the increment (but within the loop), you need:
~~~~~~
Based on your comment:
This will save the new order quantity in a variable, reload the order from the database and then do the update.