Rails provides a built-in method:
Foobar.increment_counter(:foo_count, foobar.id)
This translates into a SQL query like:
UPDATE foobars SET foo_count = foo_count + 1 WHERE id = X
Because this happens directly in the database in one atomic operation, it’s thread-safe and web-instance-safe.
If you prefer, or need something custom:
Foobar.where(id: foobar.id).update_all("foo_count = foo_count + 1")
If you absolutely need to perform other operations with the updated object:
Foobar.transaction do foobar = Foobar.lock(true).find(foobar.id) foobar.foo_count += 1 foobar.save! end
This uses a SELECT … FOR UPDATE query, locking the row until the transaction completes. But be cautious: this can reduce performance under high concurrency.
Move the increment logic into the database using a trigger:
CREATE FUNCTION increment_foo_count() RETURNS TRIGGER AS $$ BEGIN UPDATE foobars SET foo_count = foo_count + 1 WHERE id = NEW.foobar_id; RETURN NEW; END; CREATE TRIGGER trigger_increment_foo_count AFTER INSERT ON foo_count_events FOR EACH ROW EXECUTE FUNCTION increment_foo_count();
Then in Rails, you insert a row into foo_count_events, and the database handles the rest.
Work with our skilled Ruby on Rails developers to accelerate your project and boost its performance.
Hire Ruby on Rails Developer