我的Rails 3应用程序有2个模型,第三个是它们和has_many关系之间的连接表。基本上,User和Show由SavedShow加入,允许用户保存节目列表:
class Show < ActiveRecord::Base
has_many :saved_shows
has_many :users, :through => :saved_shows
end
class User < ActiveRecord::Base
has_many :saved_shows
has_many :shows, :through => :saved_shows
end
class SavedShow < ActiveRecord::Base
belongs_to :user, :counter_cache => :saved_shows_count
belongs_to :show
end
我注意到counter_cache字段(shows_saved_count)会自动递增,但不会递减。该问题的核心似乎是从用户列表中删除节目是通过删除完成的,这不会触发counter_cache的更新:
current_user.shows.delete(@show)
但是,我不能在这里调用destroy方法,因为它不仅删除了SavedShow中的User / Show关联,还删除了Show对象本身,这不是我想要的。
这种场景中的counter_cache不适合使用吗?
在2009年,似乎有一个discussion作为一个错误,并讨论了修复,但我仍然在最新的Rails 3.0中看到了这个问题。
我只是在模型中编写自己的自定义处理,但似乎没有我可以挂钩的after_delete回调(可能这就是减少首先不起作用的原因)。现在,在我自己的代码中只有一个地方可以删除关联,所以我只是手动调用更新计数器,但这似乎是一个基本的缺点或ActiceRecord与counter_cache的关联的错误,我想知道我是不是只是错过了什么。
如果这确实是counter_caches的真正问题,那么最好的解决方法是什么?
答案 0 :(得分:1)
相同的问题,但在Rails 2.3上。 值得注意的是还添加了一个触摸,如:
belongs_to :user, :counter_cache => :saved_shows_count, :touch => true
不会更新counter.delete(object)上的计数器缓存或相关的updated_at字段。
要解决这个问题通常我们会操纵连接模型,但这也有一些缺点。
答案 1 :(得分:0)
在Rails 5中解决了一个相关问题(通过连接表具有自引用计数器缓存),并按如下所示进行了修复:
class User < ActiveRecord::Base
has_many :saved_shows, :counter_cache => :saved_shows_count
has_many :shows, :through => :saved_shows
end
https://guides.rubyonrails.org/association_basics.html#options-for-has-many-counter-cache