method

increment!

Importance_3
v2.3.8 - Show latest stable - 3 notes - Class: ActiveRecord::Base
increment!(attribute, by = 1) public

Wrapper around increment that saves the record. This method differs from its non-bang version in that it passes through the attribute setter. Saving is not subjected to validation checks. Returns true if the record could be saved.

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