【问题标题】:Rails update_all with hstore使用 hstore 的 Rails update_all
【发布时间】:2013-10-08 22:37:34
【问题描述】:

使用 activerecord 用 hstore 列更新多条记录的好方法是什么?现在我正在像这样循环、更新和保存:

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 为空时才有效。

【问题讨论】:

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


    【解决方案1】:

    我自己也遇到过同样的问题,我是这样解决的:

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

    解决此问题的核心是将 update_all 操作包装在 [] 和 %() 中。我仍在努力弄清楚 %() 如何在 Postgre SQL 中定义 SET,所以如果有人有一个非常有帮助的解释。

    在我的情况下,我实际上也删除了一个键(我真的想更新键名但保留值)。因此,如果有人遇到这个问题,代码如下所示:

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

    我希望在同一个调用中执行这两个操作,但这会在 SQL 中创建一个非常奇怪的命令,其中第二个操作是作为 WHERE 子句的一部分而不是 SET 添加的。对我来说仍然有点黑魔法,但希望这会有所帮助......

    【讨论】:

      【解决方案2】:

      如果你使用

      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}))

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-13
        • 2012-11-25
        • 2011-08-25
        • 2013-10-30
        • 1970-01-01
        • 2019-10-20
        • 2022-10-21
        • 1970-01-01
        相关资源
        最近更新 更多