Search code examples
ruby-on-railsrubyactiverecord

One-to-many association counter_cache does not reload correctly in Rails


Create a Post model with lock_version and comments_count columns and a has_many relation with :comments. Create a Comment model with lock_version column and a belongs_to relation with :post, using counter_cache = true.

class Post < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :post, counter_cache: true
end

post = Post.create!
comment = Comment.create(post)
puts post.reload.comments_count # 1 (correct)
Comment.last.destroy
puts post.reload.comments_count # 1 (should be 0 - incorrect)

I tried to change rails and ruby versions but they all failed.


Solution

  • If you check the source for ActiveRecord::Locking::Optimistic (link) the last commit a7dc348 is titled 'Fix decrementing counter caches for parent records using optimistic locking' and it was created 12 hours ago. However there is no issue reference in the commit message so no hint for when the bug was introduced.

    I was able to reproduce the issue in one of my projects with activerecord-7.0.4. Then I replaced the optimistic.rb with the current version from main and it started working.