Tom*_*man 28 ruby-on-rails callback
我正在将我的旧博客帖子迁移到我的新Rails博客中,我希望他们的updated_at属性与我旧博客上的相应值相匹配(而不是他们迁移到我的新Rails博客的日期).
我怎样才能做到这一点?当我updated_at手动设置时,它会被before_save回调覆盖.
注意:此问题仅对Rails <3.2.11有效.较新版本的Rails允许您手动设置时间戳,而不会覆盖它们.
And*_*ell 28
如果它是一次性的东西,你可以打开record_timestamps或关闭.
ActiveRecord::Base.record_timestamps = false
#set timestamps manually
ActiveRecord::Base.record_timestamps = true
Run Code Online (Sandbox Code Playgroud)
当我用我的应用程序遇到这个问题时,我搜索了一下,这似乎对我来说最有意义.这是一个初始化程序,我可以在需要的地方调用:
module ActiveRecord
class Base
def update_record_without_timestamping
class << self
def record_timestamps; false; end
end
save!
class << self
def record_timestamps; super ; end
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
小智 5
从最新版本的Rails(根据iGEL评论3.2.11)开始,您可以在代码中设置updated_at属性,保存时将更改更改.
我假设rails正在跟踪已经手动更改的"脏"属性,而不是在保存时覆盖.
> note = Note.last
Note Load (1.4ms) SELECT "notes".* FROM "notes" ORDER BY "notes"."id" DESC LIMIT 1
=> #<Note id: 39, content: "A wee note", created_at: "2015-06-09 11:06:01", updated_at: "2015-06-09 11:06:01">
> note.updated_at = 2.years.ago
=> Sun, 07 Jul 2013 21:20:47 UTC +00:00
> note.save
(0.4ms) BEGIN
(0.8ms) UPDATE "notes" SET "updated_at" = '2013-07-07 21:20:47.972990' WHERE "notes"."id" = 39
(0.8ms) COMMIT
=> true
> note
=> #<Note id: 39, content: "A wee note", created_at: "2015-06-09 11:06:01", updated_at: "2013-07-07 21:20:47">
Run Code Online (Sandbox Code Playgroud)
如此简短的回答,在最新版本的rails中不再需要解决方法.
我看到两种方法可以轻松完成此操作:
在 Rails 5 中,您可以使用该touch方法并给出一个命名参数,time如touch 文档中所述
foo.touch(time: old_timestamp)
Run Code Online (Sandbox Code Playgroud)
如果您希望在 Rails 4 及更低版本中使用它或想要避免所有回调,您可以使用绕过所有安全或触摸回调和验证的update_columnorupdate_columns方法之一
foo.update_column(updated_at, old_timestamp)
Run Code Online (Sandbox Code Playgroud)
或者
foo.update_columns(updated_at: old_timestamp)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10746 次 |
| 最近记录: |