【问题标题】:Reset counter cache on all data of model重置模型所有数据的计数器缓存
【发布时间】:2014-11-05 16:48:01
【问题描述】:

我正在寻找一种漂亮的方法来更新给定模型的计数器缓存。

这是我的模型:

class GameParticipation < ActiveRecord::Base
  belongs_to :game, counter_cache: true
end

还有:

class Game < ActiveRecord::Base
  has_many   :game_participations
end

这不是比像下面的代码那样对每个元素进行迭代更好吗?

Game.ids.each {|id| Game.reset_counters(id, :game_participations) }

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    为了在一个请求中更新所有计数器缓存,我在 http://ryan.mcgeary.org/2016/02/05/proper-counter-cache-migrations-in-rails/ 上找到了灵感

    可以用 SQL 在一个请求中完成:

    ActiveRecord::Base.connection.execute <<-SQL.squish
        UPDATE games
        SET game_participations_count = (SELECT count(1)
                                   FROM game_participations
                                  WHERE game_participations.game_id = games.id)
    SQL
    

    由于所有更新都在一个请求中完成,因此执行时间要少得多。

    【讨论】:

      【解决方案2】:

      我会使用each,但除此之外,我认为答案是否定的,没有内置方法来更新多个计数器。如果这就是你所说的“美丽”?

      【讨论】:

      • 完整的活动记录请求 => 不必使用 map/each 遍历所有元素(对性能无效)
      【解决方案3】:

      也许这个 gem 'counter_culture' 可以解决你的问题。 https://github.com/magnusvk/counter_culture

      Product.counter_culture_fix_counts
      # will automatically fix counts for all counter caches defined on Product
      

      【讨论】:

      • 这是一种完全不同的计数器方式,因此无法解决用户问题。
      猜你喜欢
      • 2014-12-22
      • 2017-05-14
      • 2021-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-12
      • 1970-01-01
      相关资源
      最近更新 更多