Ruby On Rails: как запускать безопасные обновления - PullRequest
0 голосов
/ 03 августа 2010

Я использую RoR и хочу выполнять безопасные параллельные запросы на обновление.Например, когда у меня

var user = User.find(user_id)
user.visits += 1

, я получаю следующий код SQL:

SELECT * FROM Users WHERE ID=1 -- find user's visits (1)
UPDATE Users SET Visits=2 WHERE ID=1 -- 1+1=2

Но если одновременно выполняется несколько запросов, будут проблемы с блокировкой.

В соответствии с RoR API я могу использовать атрибут: lock => true, но это не то, что мне нужно.

Я нашел потрясающую функцию update_counters :

User.update_counters(my_user.id, :visits => 1)

Это дает следующий код SQL

UPDATE Users SET Visits=Visits+1 WHERE ID=@something

Отлично работает!

Теперь мой вопрос: как я могу переопределить функцию + =, чтобы вместо этого выполнить функцию update_counters?

Потому что

user.visits += 1 # better
User.update_counters(my_user.id, :visits => 1) # than this

ОБНОВЛЕНИЕ

Я только что создал следующую функцию

class ActiveRecord::Base

  def inc(column, value)

    User.update_counters(self.id, column => value)

  end

end

Есть ли другие идеи получше?

1 Ответ

1 голос
/ 03 августа 2010

Не знаю о лучших идеях, но я бы определил этот метод для класса User, а не ActiveRecord.И, возможно, increment_counter (который использует update_counters) сделает его немного более читабельным?

def inc(column, value)
  self.increment_counter(column, value)
end

Не проверял и не говорил, что это определенно лучшая идея, но, вероятно, я бы так и сделал.

Обновление: и AFAIK, вы не можете переопределить "+ =", потому что "a + = b" просто ярлык для "a = a + b", и вы, вероятно, не хотите переопределять "="использовать update_counters:)

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