2013-10-08 26 views
3

使用activerecord更新hstore列的多條記錄有什麼好方法?現在,我通過循環,更新和保存這樣的:使用hstore的rails update_all

time = Time.now.to_s 
scoped_tasks.each do |task| 
    task.data[:last_checked] = time 
    task.save! 
end 

有什麼辦法與update_all查詢做到這一點?我見過的一種解決方案如下所示:

MyModel.update_all(:properties => ActiveRecord::Coders::Hstore.dump({'a' => 1})) 

但問題是它覆蓋整個列,所以其他值將丟失。我也看到了這一點:

MyModel.update_all("data = data || hstore('a', 'blah')") 

但由於某些原因,我回去0的價值。它也看起來像只有當hstore是空的時候纔會起作用。

回答

4

我同樣的問題掙扎自己,這裏是我如何能夠解決這個問題:

MyModel.update_all([%(data = data || hstore(?,?)), 'a', 'new_value'])) 

的核心定爲這項被包裹update_all行動在[]和%()。我仍然在努力弄清楚%()是如何在Postgre SQL中定義SET的,所以如果有人有一個會超級有用的解釋。

在我的情況下,我實際上是刪除了一個密鑰(實際上我想更新密鑰名稱,但保留值)。因此,如果任何人有這個問題的代碼如下所示:

MyModel.update_all([%(data = delete("data",?)), 'a']) 

我希望在同一個呼叫做兩個動作,但是這是在被添加的部分第二動作SQL在創建了一個非常奇怪的命令WHERE子句不是SET。還是有一點的黑魔法我,但希望這可以幫助...

0

如果使用

MyModel.update_all(:properties => ActiveRecord::Coders::Hstore.dump({'a' => 1}))

那麼它會清除了其他值,如果您嘗試使用

MyModel.update_all("data = data || hstore('a', 'blah')")它只有在hstore列中有任何值時纔會起作用, 所以儘量使用兩者的組合

if (hstore_column_name).present? MyModel.update_all("data = data || hstore('a', 'blah')") else MyModel.update_all(:properties => ActiveRecord::Coders::Hstore.dump({'a' => 1}))