ActiveRecord counter_cache дает устаревший счет с гемом multi_db
Я использую multi-db gem с репликацией Slony-I на PostgreSQL в приложении Rails. Это в основном работает отлично, но в некоторых случаях наблюдается некоторая задержка репликации. В одном из случаев используется счетчик ActiveRecord counter_cache.
Для наглядности предположим следующие две модели:
class Post < ActiveRecord::Base
has_many :comments
...
end
class Comment < ActiveRecord::Base
belongs_to :post, :counter_cache => true, :touch => true
...
end
После создания комментария вызывается rjs для обновления количества комментариев:
@comment.post.comments_count
С выключенным multi-db (или записью ведомой базы данных, указывающей на master db), это работает нормально. Итак, я попробовал что-то вроде этого:
ActiveRecord::Base.connection_proxy.with_master do
post=@comment.post
count=post.comments_count
end
Это все еще дает несвежий результат. Как это делает установка:
config.cache_classes = false
Похоже, призыв к with_master
не работает Любой совет, как определить, какую базу данных использует multi-db? Или, альтернативно, о том, как бороться с такими проблемами?
2 ответа
По моему опыту, чем дальше вы получаете от "основных" сценариев использования Rails или чем больше плагинов вы собираете, тем меньше вы можете рассчитывать на расширенные функциональные возможности для совместной работы. Это особенно верно для магии ActiveRecord.
Если важно, чтобы количество комментариев оставалось актуальным, сделайте это явно. Избавьтесь от counter_cache и реализуйте after_create
а также after_destroy
обратные вызовы в вашей модели комментариев, которые увеличивают и уменьшают поле счетчика в вашей модели сообщений. (Или, возможно, более надежно, установите для них пересчитанное количество для этой области.) Это выглядит менее гладко, но вряд ли выйдет из строя при любом разумном наборе зависимостей.
Не уверен, что это решение, которое вы ищете, но я использую мазохизм для своей репликации БД, и counter_cache
функциональность работает просто отлично. так что, возможно, проблема в жемчужине, и вам нужно подать заявку.