3

我有一个为关联启用了 counter_cache 的模型:

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 观察者(或缓存清除器)中使缓存过期之外,我无法知道它何时发生只是看起来不那么干净。

有任何想法吗?

4

5 回答 5

1

我对计数器更新有类似的要求,在我的情况下,如果 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 文档

于 2019-02-01T03:00:58.093 回答
0

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

于 2011-06-13T08:16:38.197 回答
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

thenforce_expire_cache(author)是我的 AuthorSweeper 类中的一个方法,它使缓存片段过期。

于 2011-06-14T18:48:49.467 回答
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

于 2012-03-05T08:28:00.240 回答
0

在此处输入图像描述

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

从 Rails 源代码中,counter_column 也被 after_update 回调更改。

我的方法是让rails向上,自己更新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
于 2017-01-24T06:00:46.343 回答