在创建/销毁habtm计数时避免多次DB命中

时间:2013-10-22 23:14:32

标签: ruby-on-rails ruby-on-rails-3 activerecord has-and-belongs-to-many

我有GalleryPost个模型,两者之间有has_and_belongs_to_many个关系。 posts_count模型上有一个Gallery列,用于跟踪给定图库中的帖子数量。它的工作正常,但它的命中次数比看上去要多。

如果我执行类似gallery.posts.clear的操作,那么我会为每个删除的帖子获取数据库操作:

(0.3ms)  BEGIN
(0.9ms)  DELETE FROM "galleries_posts" WHERE "galleries_posts"."gallery_id" = 6 AND "galleries_posts"."post_id" IN (8, 6, 5, ..., 39, 40, 42, 41, 41, 44, 45, 47, 50, 49, 51)
(0.7ms)  UPDATE "galleries" SET "posts_count" = 54, "updated_at" = '2013-10-22 22:56:32.048238' WHERE "galleries"."id" = 6
(0.4ms)  UPDATE "galleries" SET "posts_count" = 53, "updated_at" = '2013-10-22 22:56:32.050582' WHERE "galleries"."id" = 6
(0.3ms)  UPDATE "galleries" SET "posts_count" = 52, "updated_at" = '2013-10-22 22:56:32.052247' WHERE "galleries"."id" = 6
...
(0.3ms)  UPDATE "galleries" SET "posts_count" = 3, "updated_at" = '2013-10-22 22:56:32.055607' WHERE "galleries"."id" = 6
(0.3ms)  UPDATE "galleries" SET "posts_count" = 2, "updated_at" = '2013-10-22 22:56:32.084547' WHERE "galleries"."id" = 6
(0.3ms)  UPDATE "galleries" SET "posts_count" = 1, "updated_at" = '2013-10-22 22:56:32.085752' WHERE "galleries"."id" = 6
(0.3ms)  UPDATE "galleries" SET "posts_count" = 0, "updated_at" = '2013-10-22 22:56:32.086861' WHERE "galleries"."id" = 6
(3.6ms)  COMMIT

这相当于n数据库操作以更新计数,其中n是添加或删除的帖子数。

一旦添加或删除了所有帖子,是否有办法维护依赖于仅更新图库posts_count的操作的计数?

我目前的方法在after_add / after_remove上运行:

class Gallery < ActiveRecord::Base
  ...
  has_and_belongs_to_many :posts, after_add: :increment_posts_count, 
                                  after_remove: :decrement_posts_count
  ...
  private
    def increment_posts_count(post)
      self.increment!(:posts_count)
    end

    def decrement_posts_count(post)
      self.decrement!(:posts_count)
    end
end

只有在整个操作完成后才能运行钩子吗?

0 个答案:

没有答案