Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating timestamps with #update_all

Tags:

When I have list of ids that I want to update their property the updated_at field in the database doesn't seem to change, here is what I mean :

ids = [2,4,51,124,33] MyObj.where(:id => ids).update_all(:closed => true) 

After this update is executed updated_at field doesn't change. However when I enter rails console with rails c and do this :

obj = MyObj.find(2) obj.closed = false; obj.save! 

After this statement updated_at field changes value. Why is this? I'm relying on this updated_at field in my app as I'm listening to the updates and doing whole app flow when this happens?

Edit

I just found out from dax answer that :

Timestamps  Note that ActiveRecord will not update the timestamp fields (updated_at/updated_on) when using update_all(). 

I don't want to be updating one record at a time, is there a way around this? without resorting to sql level?

like image 697
Gandalf StormCrow Avatar asked Sep 18 '13 13:09

Gandalf StormCrow


People also ask

How do you use timestamp?

The TIMESTAMP data type is used for values that contain both date and time parts. TIMESTAMP has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC. A DATETIME or TIMESTAMP value can include a trailing fractional seconds part in up to microseconds (6 digits) precision.


2 Answers

#update_all does not instantiate models.

As such, it does not trigger callbacks nor validations - and timestamp update is made in a callback.

Edit about edit :

If you want to keep the "one query to rule them all", you can update updated_at as well as :closed :

MyObj.where(:id => ids).update_all(closed: true, updated_at: DateTime.now) 

But be aware validations are still not run.

like image 165
kik Avatar answered Sep 30 '22 17:09

kik


Updates all, This method constructs a single SQL UPDATE statement and sends it straight to the database. It does not instantiate the involved models and it does not trigger Active Record callbacks or validations. Values passed to update_all will not go through ActiveRecord's type-casting behavior. It should receive only values that can be passed as-is to the SQL database.

As such, it does not trigger callbacks nor validations - and timestamp update is made in a callback.update_at is a call back for reference http://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-update_all

like image 35
Ganesh Arulanantham Avatar answered Sep 30 '22 19:09

Ganesh Arulanantham