Skip to content

Instantly share code, notes, and snippets.

@skanev
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skanev/f442394e81463588e9d6 to your computer and use it in GitHub Desktop.
Save skanev/f442394e81463588e9d6 to your computer and use it in GitHub Desktop.
An illustration of counter_cache and optimistic locking incompatiblity
require 'active_record'
require 'minitest/autorun'
require 'sqlite3'
require 'logger'
# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection 'sqlite3::memory:'
ActiveRecord::Schema.define do
create_table :people do |t|
t.string :name
t.integer :lock_version, null: false, default: 0
t.integer :vehicles_count, null: false, default: 0
t.integer :jobs_count, null: false, default: 0
t.timestamps
end
create_table :jobs do |t|
t.belongs_to :person
end
create_table :vehicles do |t|
t.belongs_to :owner, polymorphic: true
end
end
class Person < ActiveRecord::Base
has_many :jobs, dependent: :destroy, counter_cache: true
has_many :vehicles, as: :owner, dependent: :destroy, counter_cache: true
end
class Job < ActiveRecord::Base
belongs_to :person, counter_cache: true
end
class Vehicle < ActiveRecord::Base
belongs_to :owner, polymorphic: true, counter_cache: true
end
class BugTest < Minitest::Test
def test_locking_dependent_destroy_with_counter_cache
person = Person.create!
person.jobs << Job.create!
assert_equal 1, Person.find(person.id).jobs_count, "Should update the vehicle count after <<"
assert_equal 1, Person.find(person.id).lock_version, "Should bump the lock version in the database"
assert_equal 1, person.lock_version, "Should bump the lock version in the loaded model"
person.destroy
end
def test_locking_dependent_destroy_with_counter_cache_and_empty
person = Person.create!
person.jobs << Job.create!
assert_equal 1, Person.find(person.id).jobs_count, "Should update the vehicle count after <<"
person.jobs = []
assert_equal 0, Person.find(person.id).jobs_count, "Should update the vehicle count after = []"
assert_equal 2, Person.find(person.id).lock_version, "Should bump the lock version in the database"
assert_equal 2, person.lock_version, "Should bump the lock version in the loaded model"
person.destroy
end
def test_locking_polymorphic_dependent_destroy_with_counter_cache
person = Person.create!
person.vehicles << Vehicle.create!
assert_equal 1, Person.find(person.id).vehicles_count, "Should update the vehicle count after <<"
assert_equal 1, Person.find(person.id).lock_version, "Should bump the lock version in the database"
assert_equal 1, person.lock_version, "Should bump the lock version in the loaded model"
person.destroy
end
def test_locking_polymorphic_dependent_destroy_with_counter_cache_and_empty
person = Person.create!
person.vehicles << Vehicle.create!
assert_equal 1, Person.find(person.id).vehicles_count, "Should update the vehicle count after <<"
person.vehicles = []
assert_equal 0, Person.find(person.id).vehicles_count, "Should update the vehicle count after = []"
assert_equal 2, Person.find(person.id).lock_version, "Should bump the lock version in the database"
assert_equal 2, person.lock_version, "Should bump the lock version in the loaded model"
person.destroy
end
end
-- create_table(:people)
-> 0.0070s
-- create_table(:jobs)
-> 0.0007s
-- create_table(:vehicles)
-> 0.0003s
Run options: --seed 44895
# Running:
FFFF
Finished in 0.045250s, 88.3978 runs/s, 198.8950 assertions/s.
1) Failure:
BugTest#test_locking_polymorphic_dependent_destroy_with_counter_cache [counter_cache_test.rb:69]:
Should update the vehicle count after <<.
Expected: 1
Actual: 0
2) Failure:
BugTest#test_locking_dependent_destroy_with_counter_cache_and_empty [counter_cache_test.rb:61]:
Should bump the lock version in the loaded model.
Expected: 2
Actual: 0
3) Failure:
BugTest#test_locking_dependent_destroy_with_counter_cache [counter_cache_test.rb:47]:
Should bump the lock version in the loaded model.
Expected: 1
Actual: 0
4) Failure:
BugTest#test_locking_polymorphic_dependent_destroy_with_counter_cache_and_empty [counter_cache_test.rb:80]:
Should update the vehicle count after <<.
Expected: 1
Actual: 0
4 runs, 9 assertions, 4 failures, 0 errors, 0 skips
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment