在模型的所有数据上重置计数器缓存

时间:2014-09-11 16:19:53

标签: ruby-on-rails activerecord

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

以下是我的模特:

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

并且:

class Game < ActiveRecord::Base
  has_many   :game_participations
end

不是像下面的代码一样迭代每个元素吗?

Game.pluck(:id).map{|g_id| Game.reset_counters(g_id, :game_participations) }

(我正在使用Rails4和activerecord)

3 个答案:

答案 0 :(得分:14)

要在一个请求中更新所有计数器缓存,我在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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

val timeInMills = System.currentTimeMillis() + (event.timestamp - SystemClock.elapsedRealtimeNanos()) / 1000000