2012-08-01 96 views
3

我正在运行rails 3.0。我有一个对象,我想更改布尔字段但不想更改updated_at时间戳。我们不会很快升级rails,所以update_column是不可能的。我宁愿不进行模型级别的更改来支持此操作(如在此帖子中:http://blog.bigbinary.com/2009/01/21/override-automatic-timestamp-in-activerecord-rails.html),因为此类型的许多对象可能同时具有对它们调用的方法。更新属性而不更改updated_at字段

+3

你总是可以运行一些原始的SQL,不是吗? – 2012-08-01 19:20:41

+0

[有没有办法避免自动更新Rails时间戳字段?](http://stackoverflow.com/questions/861448/is-there-a-way-to-avoid-automatically-updating-rails-timestamp -fields) – 2016-05-12 18:45:34

回答

7

你可以使用.update_all:

User.where(:id => @user.id).update_all(:your_bool_field => true) 
+0

这工作,谢谢! – 2012-08-01 19:50:18

+4

请注意,这不会触发回调 – mahemoff 2013-01-21 04:33:55

6

更新前可以将record_timestamps属性设置为false。

User.record_timestamps=false 
User.first.update_attributes(:field1 => "Test") 
User.record_timestamps=true 

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

+0

没错,我在我的原始问题中发布了一篇到那篇博文的链接。我正在寻找其他方法来做到这一点,不涉及改变类的属性。 – 2012-08-01 19:47:34

+2

非线程安全 – mpoisot 2013-03-25 21:43:39

+0

这是非常危险的,当您的update_attributes正在运行时,任何更新的用户都不会被加时间戳。对于单个用户而言,对于可轻易破解的并发用户来说这不是问题。 – Batou99 2015-10-13 14:53:45

3

Rails的5允许更新记录而不更新时间戳。

在Rails 4.x中,当我们保存一个ActiveRecord对象,然后Rails的自动更新字段ActiveRecord::Base#saveupdated_atupdated_on

加触摸选项。

在Rails 5中,通过传递touch: false作为保存选项,我们可以在不更新时间戳的情况下更新对象。 touch的默认选项是true

>> user = User.new(name: 'David', email: '[email protected]') 
>> user.save 
    INSERT INTO "users" ("name", "created_at", "updated_at", "email") VALUES (?, ?, ?, ?) 
    [["name", "John"], ["created_at", 2016-05-12 05:10:22 UTC], ["updated_at", 2016-05-12 05:10:22 UTC], ["email", "[email protected]"]] 
=> true 

>> user.updated_at 
=> Thu, 12 May 2016 05:10:22 UTC +00:00 
>> user.name = "John" 
>> user.save(touch: false) 
    UPDATE "users" SET "name" = ? WHERE "users"."id" = ? [["name", "John"], ["id", 12]] 
=> true 

>> user.updated_at 
=> Thu, 12 May 2016 05:10:22 UTC +00:00