views:

42

answers:

1

I need to perform some atomic arithmetic in Rails but the only way I've found to do it for single objects is via the crude update_all class method, e.g.:

Account.update_all(["debits = debits + ?", amount], :id => id)

With collection associations, the update_all class method should be usable as an association method, since the collection will pass missing method calls on to the class with the relevant scope:

accounts.update_all(["debits = debits + ?", amount])

When dealing with collections, this is much nicer and less repetitive. However this doesn't work for singleton associations, i.e. belongs_to and has_one. The method_missing for AssociationProxy passes through to the target instance, which won't have an update_all instance method (naturally).

Is there a more elegant way to perform this arithmetic? Or is update_all as good as it gets?

A: 

You're not going to beat the performance of update_all on a large number of records by a longshot. Any reason not to use that and wrap it in a transaction?

fullware
There's no need to wrap it in a transaction since (at least with MySQL) the arithmetic performed in the single query will be atomic. That's why I chose `update_all` over `update_attribute` in the first place. As I said: it works as I've written it, but I'm looking for a more elegant way.And it's not collections I'm concerned about, so performance isn't an issue. Having access to the `update_all` method via the association is elegant enough for my tastes as it saves me from hardcoding the scope. It's updates to scalar objects and associations I'd like to clean up and make more DRY.
Ian