Skip to content

Instantly share code, notes, and snippets.

@cyberfox
Created March 10, 2017 09:37
Show Gist options
  • Save cyberfox/bb7b269ae9d3a806c0fd2cb630b7de89 to your computer and use it in GitHub Desktop.
Save cyberfox/bb7b269ae9d3a806c0fd2cb630b7de89 to your computer and use it in GitHub Desktop.
Demonstration of the problem with counter_cache in Rails 5 (and 4)
require 'test_helper'
# ActiveRecord::Schema.define(version: 20170310085807) do
# create_table "forums", force: :cascade do |t|
# t.string "title"
# t.integer "posts_count"
# t.datetime "created_at", null: false
# t.datetime "updated_at", null: false
# end
#
# create_table "posts", force: :cascade do |t|
# t.string "subject"
# t.integer "forum_id"
# t.text "body"
# t.datetime "created_at", null: false
# t.datetime "updated_at", null: false
# end
# end
#
#
# class Forum < ApplicationRecord
# has_many :posts
# end
#
# class Post < ApplicationRecord
# belongs_to :forum, counter_cache: true
# end
class PostTest < ActiveSupport::TestCase
setup do
@first = Forum.create(title: "The first forum.")
@second = Forum.create(title: "The other forum.")
@post = Post.create(subject: "The message.", body: "Nothing important.")
@post.forum = @first
@post.save
end
test "Repeatedly assigning the association increases the counter_cache count." do
5.times do
@post.forum = @second
@post.reload
end
# We never saved the post, the first forum should have 1, and the second forum should have none.
assert_equal [1, 0], [@first.reload.posts_count, @second.reload.posts_count]
# Expected: [1, 0]
# Actual: [-4, 5]
end
test "The counter_cache gets updated when an association is assigned, not saved" do
# The first forum correctly has 1 post.
assert_equal 1, @first.reload.posts_count
# Perhaps we should move the post?
@post.forum = @second
# Nah. Note, we have not saved the post.
@post.reload
# The reload reset the forum id in the post.
assert_equal @first.id, @post.forum_id
# So the posts_count should not have increased, because we never saved the changed post.
assert_equal 1, @first.reload.posts_count
# Expected: 1
# Actual: 0
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment