Performing a count inside an ActiveRecord transaction
I am writing a deliberately dumb/fun/simple online store on Rails. There
are products, units, and orders. A product is an immutable description of
what's for sale, for now there is just one product and it's id is always
1. A unit is an instance of that product that I have to sell. When in
order is created, I have the method Order#reserve_units! which does the
following in a transaction:
Looks to see how many units are available.
Compares the number of available units with the quantity requested in an
order.
If there are enough available units, update them to belong to this order.
Otherwise throw an error.
It looks like this:
def reserve_units!
quantity = self.quantity.to_i
Order.transaction do
available = Unit.where({product_id: 1, order_id: nil})
if available.count >= quantity
units = Unit.where({product_id: 1, order_id:
nil}).limit(quantity).update_all(order_id: self.id)
else
raise OutOfStockError
end
end
end
end
As far as I can tell from manual testing, RSpec unit specs, and
experimentation in the Rails console, this is working as I expect it. I
can't get my Cucumber spec to pass, and I'm having a hard time coming up
with any ideas why.
In the meantime, I'm thinking about this transaction and wondering if
works like I think it should work. Does it matter that I'm performing a
count inside a transaction? Does it matter that I'm raising a
non-ActiveRecord exception to rollback the transaction?
No comments:
Post a Comment