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.