我有Gallery
和Post
模型,has_and_belongs_to_many
两者之间有关系。模型上有一个posts_count
列Gallery
来跟踪给定画廊中有多少帖子。它工作正常,但它执行的 DB 命中次数超出了必要的范围。
如果我做类似的事情,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
只有在整个操作完成后才能运行任何钩子?