我有一个为关联启用了counter_cache的模型:
class Post
belongs_to :author, :counter_cache => true
end
class Author
has_many :posts
end
我还为每个'author'使用了一个缓存片段,并且我想在@author.posts_count
更新时使缓存过期,因为该值在UI中显示。问题是counter_cache
(increment_counter和decrement_counter)的内部似乎没有调用Author上的回调,因此我无法知道它何时发生,除非从Post观察者中使缓存失效(或缓存清扫工具,这似乎并不干净。
有什么想法吗?
答案 0 :(得分:0)
我也无法让它工作。最后,我放弃并编写了自己的cache_counter类方法,并从after_save
回调中调用它。
答案 1 :(得分:0)
我最终保持cache_counter不变,但随后通过Post的after_create回调强制缓存到期,如下所示:
class Post
belongs_to :author, :counter_cache => true
after_create :force_author_cache_expiry
def force_author_cache_expiry
author.force_cache_expiry!
end
end
class Author
has_many :posts
def force_cache_expiry!
notify :force_expire_cache
end
end
然后force_expire_cache(author)
是我的AuthorSweeper类中的一个使缓存片段到期的方法。
答案 2 :(得分:0)
好吧,我遇到了同样的问题并最终发布在你的帖子中,但我发现,由于“after_”和“before_”回调是公共方法,你可以执行以下操作:
class Author < ActiveRecord::Base
has_many :posts
Post.after_create do
# Do whatever you want, but...
self.class == Post # Beware of this
end
end
我不知道要做多少标准,但方法是公开的,所以我猜是好的。
如果您希望将缓存和模型分开,可以使用Sweepers。
答案 3 :(得分:0)
我还要求观察计数器的变化。在挖掘rails源代码之后,通过直接SQL更新来更改counter_column。换句话说,它不会触发任何回调(在您的情况下,它不会在发布更新时触发作者模型中的任何回调)。
来自rails源代码的,after_update回调也改变了counter_column。
我的方法是提高轨道,自己更新counter_column:
class Post
belongs_to :author
after_update :update_author_posts_counter
def update_author_posts_counter
# need to update for both previous author and new author
# find_by will not raise exception if there isn't any record
author_was = Author.find_by(id: author_id_was)
if author_was
author_was.update_posts_count!
end
if author
author.update_posts_count!
end
end
end
class Author
has_many :posts
after_update :expires_cache, if: :posts_count_changed?
def expires_cache
# do whatever you want
end
def update_posts_count!
update(posts_count: posts.count)
end
end
答案 4 :(得分:0)
我有类似的要求在计数器更新上执行某些操作,在我的情况下,如果counter_cache计数超过某个值,则需要执行某些操作,我的解决方案是像这样覆盖update_counters
方法:>
class Post < ApplicationRecord
belongs_to :author, :counter_cache => true
end
class Author < ApplicationRecord
has_many :posts
def self.update_counters(id, counters)
author = Author.find(id)
author.do_something! if author.posts_count + counters['posts_count'] >= some_value
super(id, counters) # continue on with the normal update_counters flow.
end
end
有关更多信息,请参见update_counters documentation。