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

If you have the created_at and updated_at DB created_at , Rails will automatically set these values ​​when creating and updating the model object. Is there a way to save the model without touching these columns?

I am citing some stale data, and I would like to set these values ​​from the corresponding values ​​in (differently) stale data. I find when I install them on the model and then save the model, Rails seems to override the input values.

Of course, I could just name the columns of the Rails model differently to prevent this, but after importing the data, I want Rails to execute its automatic timestamp.

+66
ruby timestamp ruby-on-rails activerecord
May 14 '09 at 3:40
source share
10 answers

Do this when migrating or in a rake task (or in new database seeds , if you are on the extreme rails):

 ActiveRecord::Base.record_timestamps = false begin run_the_code_that_imports_the_data ensure ActiveRecord::Base.record_timestamps = true # don't forget to enable it again! end 

You can safely set created_at and updated_at manually, Rails will not complain.

Note: This also works on individual models, for example. User.record_timestamps = false

+74
May 14 '09 at
source share

use the update_column method instead:

http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-update_column

 update_column(name, value) # Updates a single attribute of an object, without calling save. 

Validation skipped.

Callbacks are skipped.

Column

updated_at / updated_on is not updated if this column is available.

Raises ActiveRecordError when calling new objects or when the name attribute is marked readonly.

+55
Jun 24 '12 at 21:30
source share

Rails 5 provides a convenient way to update a record without updating timestamp updated_at .

You just need to pass touch:false when updating the record.

 >> user = User.first >> user.updated_at => Thu, 28 Apr 2016 20:01:57 IST +05:30 >> user.name = "Jose" >> user.save(touch: false) => true >> user.updated_at => Thu, 28 Apr 2016 20:01:57 IST +05:30 
+36
May 12 '16 at 17:06
source share

You can set the following inside your migration:

 ActiveRecord::Base.record_timestamps = false 

Or altenatively use update_all:

update_all (updates, conditions = nil, options = {})

It updates all records with data if they correspond to the set of conditions supplied, limits and order can also be included in the package. This method creates one SQL UPDATE statement and sends it directly to the database. It does not create instances of the involved models and it does not activate the active callback record.

+30
May 14 '09 at 4:00
source share

In Rails 3+ for one object, set record_timestamps for the object, not for the class. I.e.

 >> user = User.first >> user.updated_at => Tue, 12 Apr 2016 22:47:51 GMT +00:00 >> user.name = "Jose" => "Jose" >> user.record_timestamps = false >> user.save => true >> user.updated_at => Tue, 12 Apr 2016 22:47:51 GMT +00:00 >> User.record_timestamps => true 

Thus, you do not touch the global state of the model, and you do not need to remember to restore the previous setting in the ensure block.

+9
Jul 20 '16 at 22:19
source share

Since this is a one-time import, you can do the following:

  • Create a model using the legacy_created_at and legacy_updated_at .
  • Download obsolete data. Paste in the model fields as desired. You can use #save and not worry at all about using update_all or the like, and you can use callbacks if necessary.
  • Create a hyphen to rename the columns to created_at and updated_at .
+3
May 14 '09 at 4:11
source share

I like to use the mixin module to temporarily disable stamping in a block:

 module WithoutTimestamps def without_timestamps old = ActiveRecord::Base.record_timestamps ActiveRecord::Base.record_timestamps = false begin yield ensure ActiveRecord::Base.record_timestamps = old end end end 

Then you can use it where you need it.

 class MyModel < ActiveRecord::Base include WithoutTimestamps def save_without_timestamps without_timestamps do save! end end end 

Or just one-time:

 m = MyModel.find(1) WithoutTimestamps.without_timestamps do m.save! end 
+3
21 oct. '13 at 21:12
source share

If not in bulk import, can you override the should_record_timestamps value? The method on your model is to add new checks when updating the updated_at column.

+2
Oct 08 '13 at
source share

Referring to other answers, I was surprised to find that disabling timestamps for one model, for example, in:

 User.record_timestamps = false 

worked for my development database, but not in my preliminary database, which runs on another server. However, it works if I turn off timestamps for all models using

 ActiveRecord::Base.record_timestamps = false 

(Situation: created_at attribute changed during migration)

+2
Mar 19 '14 at 7:58
source share
+1
Dec 16 '10 at 0:22
source share



All Articles