ActiveRecord counter_cache дает устаревший счетчик с помощью драгоценного камня multi_db
-
20-09-2019 - |
Вопрос
Я использую драгоценный камень multi-db с репликацией Slony-I на PostgreSQL в приложении Rails.В основном это работает отлично, но в некоторых случаях репликация имеет небольшую задержку.Один из случаев связан с кэшем счетчика ActiveRecord.
Для ясности предположим следующие две модели:
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
Если несколько баз данных отключены (или запись для подчиненной базы данных указывает на главную базу данных), это работает нормально.Итак, я попробовал что-то вроде этого:
ActiveRecord::Base.connection_proxy.with_master do
post=@comment.post
count=post.comments_count
end
Это по-прежнему дает устаревший результат.Как и настройка:
config.cache_classes = false
Похоже на вызов with_master
не работает.Есть какие-нибудь советы о том, как определить, какую базу данных использует multi-db?Или, как вариант, о том, как бороться с такими проблемами?
Решение
По моему опыту, чем дальше вы отходите от «основных» вариантов использования Rails или чем больше плагинов вы устанавливаете, тем меньше вы можете рассчитывать на расширенную функциональность для совместной работы.Это особенно верно в отношении магии ActiveRecord.
Если важно, чтобы количество комментариев оставалось актуальным, сделайте это явно.Избавьтесь от counter_cache и реализуйте after_create
и after_destroy
обратные вызовы в вашей модели комментариев, которые увеличивают и уменьшают поле счетчика в вашей модели публикации.(Или, возможно, более надежно, установите для них пересчитанное количество для этой области.) Это выглядит менее гладко, но вряд ли потерпит неудачу при любом разумном наборе зависимостей.
Другие советы
Не уверен, что это решение, которое вам нужно, но я использую мазохизм для моей репликации БД и counter_cache
функционал работает нормально.так что возможно проблема в геме и нужно подавать тикет.