Rails counter cache not updating

Rated 3.87/5 based on 520 customer reviews

DELETE FROM posts_tags WHERE posts_tags.tag_id = 1 AND posts_tags.post_id = 99 UPDATE posts SET tags_count = tags_count - 1 WHERE = 99; DELETE FROM tags WHERE = 1 -- ====================== -- TOTAL QUERIES: 2×N 2 -- ======================class Post # FIELDS: content, total_tags has_and_belongs_to_many :tags before_save :update_total_tags def update_total_tags self.total_tags = tag_ids.count end end class Tag # FIELDS: title has_and_belongs_to_many :posts before_destroy :update_posts def update_posts Post.where(id: post_ids).update_all('total_tags = total_tags - 1') end end INSERT INTO posts (content, total_tags) VALUES ("Lorem ipsum", 99) INSERT INTO posts_tags (post_id, tag_id) VALUES (1, 1); INSERT INTO posts_tags (post_id, tag_id) VALUES (1, 2); ...

( Record/Counter Cache/reset_counters) if you want to get to a clean state in order to pinpoint where it goes off.

When a new post is created with a few tags (actually 99 tags for the sake of example), Active Record will perform multiple updates: INSERT INTO posts (content) VALUES ("Lorem ipsum") INSERT INTO taggings (post_id, tag_id) VALUES (1, 1); UPDATE posts SET tags_count = tags_count 1 WHERE = 1; INSERT INTO taggings (post_id, tag_id) VALUES (1, 2); UPDATE posts SET tags_count = tags_count 1 WHERE = 1; ...

INSERT INTO taggings (post_id, tag_id) VALUES (1, 99); UPDATE posts SET tags_count = tags_count 1 WHERE = 1; -- ====================== -- TOTAL QUERIES: 2×N 1 -- ======================SELECT * FROM posts INNER JOIN posts_tags ON = posts_tags.post_id WHERE posts_tags.tag_id = 1 DELETE FROM posts_tags WHERE posts_tags.tag_id = 1 AND posts_tags.post_id = 1 UPDATE posts SET tags_count = tags_count - 1 WHERE = 1; DELETE FROM posts_tags WHERE posts_tags.tag_id = 1 AND posts_tags.post_id = 2 UPDATE posts SET tags_count = tags_count - 1 WHERE = 2; ...

You may want to consider using has_many :through instead. I can successfully update the counter cache when adding or destroying the associated record. You'll have to set up an observer or callback to update the counter cache every time you change a task.

Alternatively you can try building your own custom counter cache by using the after_add and after_remove callbacks. You may want to ask this on where I can go into more detail.

rails counter cache not updating-39

rails counter cache not updating-89

rails counter cache not updating-28

The model definitions look like this: The only problem left is that the counts are off if there are already posts and comments in the database.

For instance, what is the best way, or a very good way to go about handling a situation where you want to count only unread messages and also count the total number of messages with a counter_cache? but the unread have some conditions that would obviously need to be checked.

I've had nothing but problems implementing counter_cache in an ajaxy application.

I migrate tables where some inital row values in the db are generated using Model.create in the migration class, which cannot be done with counter caching.

Instead I just made a rake file with the same Model.create calls and that seems to work, if I just generate the values in a correct order. Ryan, do you have any experience or advice on working with counter_caches that also have conditions on them?

Leave a Reply