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現在の時刻と設定しようとしている新しい時刻が少なくとも 1 秒異なる場合にのみ変更が見られるようです。Activerecord コードのどこでこれが発生するかを見つけることができませんでしたが、これは問題を示しています。100 ミリ秒間隔で 2 回作成し、1 回目でレコードを更新しますが、2 回目の更新はデータベースにコミットしません。

[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 に答える