Rails中has_many through关联中的counter_cache
Rails中has_many through关联中的counter_cache
我正在使用counter_culture
gem来缓存我的计数。以下是模型:\n
User模型
\n
has_many :memberships, dependent: :destroy
\n
Membership模型
\n
has_many :authorables, dependent: :destroy has_many :posts, through: :authorables
\n
Post模型
\n
has_many :authorables, dependent: :destroy has_many :authors, through: :authorables, source: :membership
\n
Authorable模型
\n
belongs_to :membership belongs_to :post counter_culture :post, column_name: "authors_count"
\n如你所见,我正在缓存post
模型上的authors_count
。\n当我更新帖子时,post.update(authors: [membership])
计数器会增加1,但当我尝试删除作者时post.update(authors: [])
,计数器不会减少。\n有没有办法修复这个问题?
Rails中的counter_cache是一种机制,用于在关联模型之间保持计数器的同步更新。但是在使用has_many through关联时,counter_cache无法正常工作的问题,也就是无法通过更新中间模型来触发计数器的更新。
问题出现的原因是,counter_culture gem是基于Rails的回调机制来实现计数器的更新的。而post.update(authors: [])
这样的代码无法触发Rails的回调。同样,post.authors.find(1).delete
也无法触发回调。
解决这个问题的方法是编写一个函数,解析authors并触发destroy操作,以触发回调并更新counter_cache列。可以考虑使用下面的代码:
some_conditions = { id: [1,2,3] } post.authors.where(some_conditions).each(&:destroy)
以上就是关于“Rails counter_cache on has_many through”问题的出现原因及解决方法。如果想了解更多关于ActiveRecord回调的内容,可以参考这个well-described answer。作者也确认了这个解决方法的正确性,并表示现在已经按预期工作了。