Nadpisanie atrybutu licznika

witam
są przykładowo modele Group i Person, group has_many persons.
Jest też tabela visits, ale dodatkowo w celach lepszej wydajnosci, obie tabele zawierają visits_count.
Każde wejście do Person jest zapisywane w obu tabelach, visits_count w group to suma wejsc do wszystkich persons w grupie.

if @visit.save @person.update_attribute(:visits_count, @person.visits_count + 1) @group.update_attribute(:visits_count, @group.visits_count + 1) end
Obawiam się sytuacji że dwie osoby wejdą równoczesnie do tego samego person czyli A pobiera visits_count, potem B pobiera visits_count, A zapisuje visits_count, B zapisuje i … wizyta A nie zostaje zaliczona.
Czy dobry rozwiązaniem było by zamiast użycia obiektów w tym przypadku zwiekszac licznik za pomocą mysqlowej komendy visits_count = visits_count + 1, one z tego co wiem są kolejkowane. Jakieś inne porady ?
Opcja crona który zlicza wizyty co jakiś czas odpada ponieważ możliwe że tabela visits będzie co jakiś czas wyczyszczona ze starszych rekordów.

Po pierwsze czemu inkrementujesz to w kontrolerze? Na moje oko powinieneś to przenieść do modelu, ustawiając odpowiedni callback. Możesz też wykorzystać metodę increment_counter, która działa wykonując visits_count = visits_count + 1
Ostatecznie otrzymałbyś coś takiego:

[code=Ruby]class Visit < ActiveRecord::Base
belongs_to :person
belongs_to :group
after_create :update_counters

private
def update_counters
Person.increment_counter(:visits_count, person_id)
Group.increment_counter(:visits_count, group_id)
end
end[/code]

dzięki, będzie oczywiście w modelu, to było robocze rozwiązanie żeby później za duzo nie zmieniać. czyli rozumiem ze incremant counter jest bezpieczny pod względem tego co wyżej napisałem ?
Jedna uwaga, zauważyłem że jeśli chce na bieżąco wyświetlić zmianę liczby dla grupy, np jeśli @visit.save było wywoływane ajaxem, to trzeba dać @grup.reload w kontrolerze po zapisaniu wizyty

Tak, ponieważ wykorzystuje metodę update_counters
http://apidock.com/rails/ActiveRecord/Base/update_counters/class
w dokumentacji jest przykład kodu SQL, który ona generuje.

Co do drugiego pytania to zobacz w logach w jakiej
kolejności wykonywanie są zapytania (nie podałeś kodu).
Pamiętaj też, że w obrębie pojedynczego requesta powtarzające
się zapytania są cache’owane.

Przy użyciu metody klasowej działa wszystko ładnie, w logu jest SET views_count = COALESCE(views_count, 0) + 1 WHERE (id = 6031) .
Co ciekawe próbowałem osiągnąć to samo ze pomocą metody instancyjnej increment! i tutaj już inkrementacja odbywa sie w mniej bezpieczny sposób. W jednym zapytaniu pobierana jest liczba rekordów a w innym jest SET views_count = 5, czyli teoretycznie przez ten czas views_count mogło już zostać zmienione przez kogoś innego.