为什么update_attribute不会更改我的timestamp列

时间:2013-02-20 18:59:25

标签: ruby-on-rails-3 postgresql activerecord ruby-on-rails-3.2

我有一个带有时间戳列的模型,queued_at。

为什么update_attribute(:queued_at, Time.now)没有写入数据库?这只会偶尔发生。这是一个经常更新的属性。 update_column似乎一直都在工作。

我正在使用带有postgres的rails 3.2.12。

rails 3.1.11中不存在此问题。

这些项目展示了“问题”:

  1. https://github.com/johnnaegle/scratch/tree/feature/rails_3.2.12
  2. https://github.com/johnnaegle/scratch/tree/feature/rails_3.1.11

2 个答案:

答案 0 :(得分:3)

似乎active_record足够聪明,可以知道正在更新的值是相同还是足够接近(在时间戳的情况下)它将避免SQL写入 - 性能节省。我已经成功强制通过在update_attribute调用之后“触摸”相关对象的模型来写入updated_at字段

foo.update_attribute :last_status, status
foo.touch
## log entry
##  UPDATE `foo` SET `updated_at` = '2013-07-25 19:56:36' WHERE `foo`.`id` = 55

答案 1 :(得分:1)

如果您尝试设置的当前时间和新时间相差至少一秒,update_attribute似乎只会看到更改。我无法在activerecord代码中找到这种情况,但这证明了这个问题。我创建两次,100ms appart,第一次更新记录,但第二次更新不提交到数据库。

[15] pry(main)> x=Time.now;sleep(0.1);y=Time.now
=> 2013-02-20 12:06:57 -0600

[16] pry(main)> x.strftime("%Y-%m-%d %H:%M:%S.%L")
=> "2013-02-20 12:06:57.185"

[17] pry(main)> y.strftime("%Y-%m-%d %H:%M:%S.%L")
=> "2013-02-20 12:06:57.286"

[18] pry(main)> kat = Kitten.first
  Kitten Load (1.2ms)  SELECT "kittens".* FROM "kittens" LIMIT 1
=> #<Kitten id: 1,  queued_at: "2013-02-13 20:38:00">

[19] pry(main)> kat.queued_at = x
=> 2013-02-20 12:06:57 -0600

[20] pry(main)> kat.save
   (0.5ms)  BEGIN
   (0.6ms)  UPDATE "kittens" SET "queued_at" = '2013-02-20 18:06:57.185870' WHERE "kittens"."id" = 1
   (1.3ms)  COMMIT
=> true

[21] pry(main)> kat.queued_at = y
=> 2013-02-20 12:06:57 -0600

[22] pry(main)> kat.save
   (0.2ms)  BEGIN
   (0.2ms)  COMMIT
=> true