有没有办法避免自动更新Rails时间戳字段?

Eth*_*han 66 ruby activerecord timestamp ruby-on-rails

如果您有DB列created_at,updated_atRails将在您创建和更新模型对象时自动设置这些值.有没有办法保存模型而不触及那些列?

我正在引入一些遗留数据,我想从(不同命名的)遗留数据字段中的相应值设置这些值.我发现当我在模型上设置然后保存模型时,Rails似乎会覆盖传入的值.

当然,我可以不同地命名Rails模型列以防止这种情况,但是在导入数据之后,我希望Rails执行其自动时间戳操作.

Aug*_*aas 74

在迁移或rake任务中执行此操作(如果您在边缘轨道上,则在新数据库种子中执行此操作):

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
Run Code Online (Sandbox Code Playgroud)

你可以安全地设置created_atupdated_at手动,Rails不会抱怨.

注意:这也适用于单个模型,例如 User.record_timestamps = false

  • 你甚至可以将它拉成一个方法,例如`def without_timestamps old = ActiveRecord :: Base.record_timestamps ActiveRecord :: Base.record_timestamps = false begin yield确保ActiveRecord :: Base.record_timestamps = old end end` (3认同)
  • 我认为http://stackoverflow.com/a/37193298/1214748要好得多.它不会在整个应用程序中全局关闭它 (2认同)

yaw*_*awl 55

改为使用update_column方法:

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.
Run Code Online (Sandbox Code Playgroud)

验证被跳过.

跳过回调.

如果该列可用,则不更新updated_at/updated_on列.

在新对象上调用时,或者当name属性标记为只读时,引发ActiveRecordError.


Sub*_*dra 36

Rails 5提供了一种更新记录的便捷方式,无需更新它的时间戳updated_at:https://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-save

您,只需要touch:false在更新记录时通过.

>> 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
Run Code Online (Sandbox Code Playgroud)

  • 似乎有点奇怪,在执行“更新”时相同的选项不起作用。您需要将其分为两个操作,如下所示。 (3认同)

Tob*_*ede 30

您可以在迁移中设置以下内容:

ActiveRecord::Base.record_timestamps = false
Run Code Online (Sandbox Code Playgroud)

或者使用update_all:

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

如果所有记录与提供的一组条件匹配,则更新所有记录,也可以提供限制和订单.此方法构造单个SQL UPDATE语句并将其直接发送到数据库.它不会实例化所涉及的模型,也不会触发Active Record回调.


Chu*_*son 9

在Rails 3+中,对于单个对象,record_timestamps为对象而不是类设置.也就是说,

>> 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
Run Code Online (Sandbox Code Playgroud)

这样,您不会触摸模型的全局状态,也不必记住恢复ensure块中的先前设置.