method

increment!

Importance_2
v1.0.0 - Show latest stable - 3 notes - Class: ActiveRecord::Base
increment!(attribute) public

Increments the attribute and saves the record.

Show source
Register or log in to add new notes.
September 13, 2010 - (>= v1.0.0)
2 thanks

No concurrency

If you want to handle concurrency, this doesn’t work:

a = Article.first
b = Article.first
a.increment!(:view_count)
b.increment!(:view_count)
a.reload.view_count # -> 1
b.reload.view_count # -> 1

Instead, use SQL:

def increment_with_sql!(attribute, by = 1)
  raise ArgumentError("Invalid attribute: #{attribute}") unless attribute_names.include?(attribute.to_s)
  original_value_sql = "CASE WHEN `#{attribute}` IS NULL THEN 0 ELSE `#{attribute}` END"
  self.class.update_all("`#{attribute}` = #{original_value_sql} + #{by.to_i}", "id = #{id}")
  reload
end
January 5, 2015
0 thanks

SQL Injection?

Note that the version of leente and timdorr are probably vulnerable to SQL Injection (through attribute param).

Probably you want to look into with_lock instead of handcrafting SQL.

April 4, 2013 - (>= v1.0.0)
0 thanks

increment_by_sql for PG

Note, if you’re using the code below for incrementing by SQL with a Postgres database, it’s not going to like the backticks. Just remove them:

def increment_with_sql!(attribute, by = 1)
  raise ArgumentError("Invalid attribute: #{attribute}") unless attribute_names.include?(attribute.to_s)
  original_value_sql = "CASE WHEN #{attribute} IS NULL THEN 0 ELSE #{attribute} END"
  self.class.update_all("#{attribute} = #{original_value_sql} + #{by.to_i}", "id = #{id}")
  reload
end