Reputation: 3282
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!
Upvotes: 0
Views: 132
Reputation: 2191
You aren't saving the record. After the increment (but within the loop), you need:
order.deal.save
~~~~~~
Based on your comment:
@new_orders.each do |order|
order_quantity = order.quantity
order.reload
order.deal.update_attribute(:order_count, order.deal.order_count + order_quantity)
end
This will save the new order quantity in a variable, reload the order from the database and then do the update.
Upvotes: 1