How to update a single attribute without touching the updated_at attribute?

How can I achieve this?

tried to create 2 methods, called

def disable_timestamps
  ActiveRecord::Base.record_timestamps = false
end

def enable_timestamps
  ActiveRecord::Base.record_timestamps = true
end

and the update method itself:

def increment_pagehit
  update_attribute(:pagehit, pagehit+1)
end

turn timestamps on and off using callbacks like:

before_update :disable_timestamps, :only => :increment_pagehit
after_update :enable_timestamps, :only => :increment_pagehit

but it's not updating anything, even the desired attribute (pagehit).

Any advice? I don't want to have to create another table just to count the pagehits.


As an alternative to update_attribute, In Rails 3.1+ you can use update_column.

update_attribute skips validations, but will touch updated_at and execute callbacks.

update_column skips validations, does not touch updated_at, and does not execute callbacks.

Thus, update_column is a great choice if you don't want to affect updated_at and don't need callbacks.

See http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html for more information.

Also note that update_column will update the value of the attribute in the in-memory model and it won't be marked as dirty. For example:

p = Person.new(:name => "Nathan")
p.save
p.update_column(:name, "Andrew")
p.name == "Andrew" # True
p.name_changed? # False

If all you're wanting to do is increment a counter, I'd use the increment_counter method instead:

ModelName.increment_counter :pagehit, id

Is there a way to avoid automatically updating Rails timestamp fields?

Or closer to your question:

http://blog.bigbinary.com/2009/01/21/override-automatic-timestamp-in-activerecord-rails.html


it is not a good idea to do this:

self.class.update_all({ pagehit: pagehit+1 }, { id: id })

it should be

self.class.update_all("pagehit = pagehit + 1", { id: id })

the reason is if two requests are parallel, on the first version both will update the pagehits with the same number, as it uses the number saved in the Ruby memory. The second option uses the sql server to increase the number by 1, in case two of these queries come at the same time, the server will process them one after the other, and will end up with the correct number of pagehits.