ActiveRecord Counter_cache dando contagem obsoleta com gem Multi_DB
-
20-09-2019 - |
Pergunta
Estou usando a gem Multi-DB com replicação Slony-I no PostgreSQL em um aplicativo Rails. Isso funciona principalmente perfeitamente, mas há um pouco de atraso de replicação em certos casos. Um dos casos envolve um ActiveRecord Counter_cache.
Para maior clareza, suponha os dois modelos a seguir:
class Post < ActiveRecord::Base
has_many :comments
...
end
class Comment < ActiveRecord::Base
belongs_to :post, :counter_cache => true, :touch => true
...
end
Após a criação de um comentário, o RJS é chamado para atualizar os comentários da contagem de comentários com:
@comment.post.comments_count
Com o Multi-DB desligado (ou a entrada para o banco de dados de escravos apontando o db mestre), isso funciona bem. Então, eu tentei algo assim:
ActiveRecord::Base.connection_proxy.with_master do
post=@comment.post
count=post.comments_count
end
Isso ainda dá um resultado obsoleto. Como a configuração:
config.cache_classes = false
Parece a chamada para with_master
não está funcionando. Algum conselho sobre como determinar qual banco de dados multi-db está usando? Ou, alternativamente, sobre como lidar com esses problemas?
Solução
Na minha experiência, quanto mais longe você obtém dos casos de uso de trilhos "mainstream" ou mais plugins empilhados, menos você pode contar com a funcionalidade avançada para trabalhar juntos. Isso é particularmente verdadeiro com o ActiveRecord Magic.
Se for importante que sua contagem de comentários permaneça atualizada, faça -o explicitamente. Livre -se do Counter_cache e implemente after_create
e after_destroy
Retornos de chamada em seu modelo de comentário que incrementam e diminuem o campo de contagem em seu modelo de postagem. (Ou, talvez mais confiável, defina -os para a contagem recalculada para esse escopo.) Parece menos liso, mas provavelmente não falhará sob nenhum conjunto razoável de dependências.
Outras dicas
Não tenho certeza se é a solução que você procura, mas eu uso masoquismo para minha replicação de banco de dados e o counter_cache
A funcionalidade está funcionando muito bem. Então, talvez o problema esteja na jóia e você precise registrar um ticket.