2011-05-07 65 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 
相關問題