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
4

2 回答 2

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
于 2013-07-25T20:09:33.240 回答
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
于 2013-02-20T18:59:24.860 回答