2011-05-07 63 views
2

我已经counter_cache为关联启用的模型:如何在使用'counter_cache'时调用after_save回调?

class Post 
    belongs_to :author, :counter_cache => true 
end 

class Author 
    has_many :posts 
end 

我也使用一个缓存片段每个“作家”,我想到期高速缓存每当@author.posts_count被更新,因为该值是表示UI。问题是counter_cache(increment_counter和decrement_counter)的内部似乎没有调用Author的回调函数,所以我无法知道它何时发生,除非从Post观察者(或缓存清理器)中过期缓存,这似乎并不干净。

任何想法?

回答

0

我结束了保持cache_counter,因为它是,但后来通过邮政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类中的方法,使用期限缓存片段。

+0

什么是在具有反缓存在所有那么点? – 2012-01-25 12:55:26

0

我也无法让它工作。最后,我放弃了自己写的cache_counter方法,并从after_save回调中调用它。

+0

由于地塞米松,我会后的解决方案,我想出以及 – Carter 2011-06-14 18:48:27

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

0

enter image description here

我也有一定的要求看柜台的变化。在挖掘rails源代码之后,通过直接的SQL更新来改变counter_column。换句话说,它不会触发任何回调(在你的情况下,当Post更新时它不会触发Author模型中的任何回调)。

from rails源代码,counter_column也被after_update回调改变了。

我的做法是给轨道的一路上涨,由我更新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 
相关问题