Rails 3: обновлять counter_cache, только если опубликовано - PullRequest
6 голосов
/ 02 мая 2011

Это сложный вопрос.

У меня есть проект с несколькими типами контента, такими как Article, Review и т. Д. Каждый тип контента имеет комментарии, комментарии полиморфны, поскольку они могут принадлежать к любому типу контента.

Я хочу разместить счетчик общих комментариев на всех своих страницах контента, чтобы показать, сколько комментариев, и я добавил кеш счетчика для этого. (Что-то вроде @ article.comments.count - это больше запросов, и, поскольку я использую гем Ancestry для многопоточных комментариев, дочерние комментарии не учитываются в этом числе, а только корневые.)

Кеш счетчика отлично работает и показывает точное количество комментариев, но, как всегда, есть одна маленькая хитрость. Комментарии не всегда публикуются сразу, только зарегистрированные пользователи могут публиковать их немедленно, и эти комментарии имеют статус «2». Незарегистрированные пользователи попадают в очередь на модерацию; эти комментарии имеют статус «1».

Проблема в том, что кэш счетчика считает их одинаково, поэтому, если у вас есть четыре комментария на модерации и один одобренный комментарий, общее количество будет равно 5.

Есть ли способ добавить исключение в кеш счетчика, чтобы запретить его приращение, если значение comment.status не равно 2? Аналогично, когда в бэкэнде в ресурсе комментариев и в настройке этого комментария публикуется комментарий (при этом он имеет статус 2), существует ли способ (модель, контроллер или иное) сделать кэш счетчика для приращения связанного с ним полиморфного типа / типа контента?

comments.rb

 # Comments
 has_many :comments, :as => :commentable, :dependent => :destroy
 accepts_nested_attributes_for :comments

article.rb

belongs_to :commentable, :polymorphic => TRUE, :touch => TRUE, :counter_cache => TRUE 

1 Ответ

5 голосов
/ 02 мая 2011

На данный момент я могу думать о том, что вам, возможно, придется предоставить свои собственные столбцы кэша счетчика в модели и увеличивать / уменьшать их по мере необходимости. т.е.

active_comments_count
pending_comments_count

Затем в вашей модели вы можете вызвать метод update_comment_count с помощью обратного вызова .

Это больше усилий на вашей стороне, но я уверен, что этот подход будет работать.

...