Last active
August 29, 2015 14:05
-
-
Save skanev/f442394e81463588e9d6 to your computer and use it in GitHub Desktop.
An illustration of counter_cache and optimistic locking incompatiblity
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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