2013-12-17 147 views
2

問題如下:我有一個模型--MyModel1和MyModel2,它們有關係--MyModel1 has_many MyModel2's。現在,數據庫是Postgres的,並且對MyModel2,其上插入/更新/刪除的更新在某些時刻MyModel1的updated_at領域的數據庫觸發器:`Time.now.utc` Rails和`now()在時區之間的區別'utc'` postgres

UPDATE my_model1 SET updated_at = (now() at time zone 'utc') 

現在,我有一個規範,驗證是否它真的做了我想要的東西:

it "updates the updated_at field" do 
    mymodel1instance.update_attributes(updated_at: Time.now - 1.day) 
    mymodel2build.save! # mymodel2build belongs_to mymodel1instance 
    mymodel1instance.updated_at.to_s.should == Time.now.utc.to_s 
    end 

我相信可以有延遲或什麼的。奇怪的是mymodel2build.updated_at字段是Time.now.utc的1秒AHEAD。

規格結果:

expected: "2013-12-17 13:30:33 UTC" 
     got: "2013-12-17 13:30:32 UTC" (using ==) 

注:規格並不總是失敗,它只是從時間沒有時間。 任何人都可以解釋爲什麼發生這種情況?

+1

保存記錄然後運行檢查需要一定的時間,大約1秒。 –

+0

是的,同意。事情是,被保存實體的時間比當前時間早1秒,因爲對象在將來被保存。 –

+0

保存實體的時間比當前時間晚一秒。您期待'13:30:33',但數據庫中的那個是'13:30:32' – usha

回答

2

在Postgres裏,你有now()clock_timestamp()

  • now()將返回其在當前事務開始的時間戳。 (或者說,如果它是一個事務外部的只讀查詢)
  • clock_timestamp()將像Ruby的Time.now一樣返回時鐘的時間戳。

另外,您的測試等同於測試a)Ruby返回系統時鐘的當前時間和b)實際發生在單個字段上的Postgres更新。這使得它與編寫測試來驗證2 + 2 = 4一樣有用。當然不是說這些測試不可能失敗;只是,imho,你可能有更重要的事情需要花費時間,即測試抽象層次更高的事物,例如公共API端點。 (後者比通過單元測試凍結自己的內部結構更重要。)