Атомная арифметика в Rails - PullRequest
1 голос
/ 29 июня 2010

Мне нужно выполнить некоторую атомарную арифметику в Rails, но я нашел единственный способ сделать это для отдельных объектов - через грубый метод класса update_all, например ::100100

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

В случае ассоциаций коллекции метод класса update_all должен использоваться в качестве метода ассоциации, поскольку коллекция будет передавать отсутствующие вызовы метода в класс с соответствующей областью действия:

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

При работе с коллекциями это намного приятнее и менее повторяется. Однако это не работает для одноэлементных ассоциаций, то есть belongs_to и has_one. method_missing для AssociationProxy проходит к целевому экземпляру, у которого не будет метода экземпляра update_all (естественно).

Есть ли более элегантный способ выполнить эту арифметику? Или update_all настолько хорош, насколько это возможно?

Ответы [ 2 ]

2 голосов
/ 27 марта 2011

Я думаю, вы ищете метод update_counters.Он позволяет указать произвольное значение приращения и по-прежнему выполняет элементарную операцию:

Account.update_counters id, :debits => amount

Он также поддерживает выполнение операции с коллекциями идентификаторов без цикла:

Account.update_counters [1, 2, 3, 4, 5], :debits => amount

Извлечьсамая последняя документация по Rails 3.0.x:

http://api.rubyonrails.org/classes/ActiveRecord/CounterCache.html#method-i-update_counters

0 голосов
/ 29 июня 2010

Вы не станете побеждать производительность update_all на большом количестве записей в долгосрочной перспективе. Есть ли причина не использовать это и не включать в транзакцию?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...