Add tests for associations without counter_cache

Assert that counter_cache behaviour is not used on belongs_to or
has_many associations if the option is not given explicitly.
This commit is contained in:
Tristan Gamilis 2015-04-09 14:53:15 +10:00
parent e0cb21f5f7
commit 5435230451
4 changed files with 43 additions and 0 deletions

@ -19,6 +19,9 @@
require 'models/line_item'
require 'models/column'
require 'models/record'
require 'models/ship'
require 'models/treasure'
require 'models/parrot'
class BelongsToAssociationsTest < ActiveRecord::TestCase
fixtures :accounts, :companies, :developers, :projects, :topics,
@ -311,6 +314,22 @@ def test_with_select
assert_equal 1, Company.all.merge!(:includes => :firm_with_select ).find(2).firm_with_select.attributes.size
end
def test_belongs_to_without_counter_cache_option
# Ship has a conventionally named `treasures_count` column, but the counter_cache
# option is not given on the association.
ship = Ship.create(name: 'Countless')
assert_no_difference lambda { ship.reload.treasures_count }, "treasures_count should not be changed unless counter_cache is given on the relation" do
treasure = Treasure.new(name: 'Gold', ship: ship)
treasure.save
end
assert_no_difference lambda { ship.reload.treasures_count }, "treasures_count should not be changed unless counter_cache is given on the relation" do
treasure = ship.treasures.first
treasure.destroy
end
end
def test_belongs_to_counter
debate = Topic.create("title" => "debate")
assert_equal 0, debate.read_attribute("replies_count"), "No replies yet"

@ -31,6 +31,8 @@
require 'models/pirate'
require 'models/ship'
require 'models/ship_part'
require 'models/treasure'
require 'models/parrot'
require 'models/tyre'
require 'models/subscriber'
require 'models/subscription'
@ -932,6 +934,25 @@ def test_deleting_before_save
assert_equal 0, new_firm.clients_of_firm.size
end
def test_has_many_without_counter_cache_option
# Ship has a conventionally named `treasures_count` column, but the counter_cache
# option is not given on the association.
ship = Ship.create(name: 'Countless', treasures_count: 10)
assert_not ship.treasures.instance_variable_get('@association').send(:has_cached_counter?)
# Count should come from sql count() of treasures rather than treasures_count attribute
assert_equal ship.treasures.size, 0
assert_no_difference lambda { ship.reload.treasures_count }, "treasures_count should not be changed" do
ship.treasures.create(name: 'Gold')
end
assert_no_difference lambda { ship.reload.treasures_count }, "treasures_count should not be changed" do
ship.treasures.destroy_all
end
end
def test_deleting_updates_counter_cache
topic = Topic.order("id ASC").first
assert_equal topic.replies.to_a.size, topic.replies_count

@ -1,6 +1,7 @@
class Treasure < ActiveRecord::Base
has_and_belongs_to_many :parrots
belongs_to :looter, :polymorphic => true
# No counter_cache option given
belongs_to :ship
has_many :price_estimates, :as => :estimate_of

@ -671,6 +671,8 @@ def except(adapter_names_to_exclude)
t.string :name
t.integer :pirate_id
t.integer :update_only_pirate_id
# Conventionally named column for counter_cache
t.integer :treasures_count, default: 0
t.datetime :created_at
t.datetime :created_on
t.datetime :updated_at