From c8be4574a2a35c896560ff58b26111ad6dd9d60f Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Tue, 31 May 2016 11:35:46 -0400 Subject: [PATCH] `ActiveRecord::Base#hash` should differ between classes Prior to this change, we would get collisions if Active Record objects of different classes with the same ID were used as keys of the same hash. It bothers me slightly that we have to allocate inside of this method, but Ruby doesn't provide any way to hash multiple values without allocation --- activerecord/lib/active_record/core.rb | 2 +- activerecord/test/cases/base_test.rb | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index f936e865e4..d45ca9b24b 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -432,7 +432,7 @@ def ==(comparison_object) # [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ] def hash if id - id.hash + [self.class, id].hash else super end diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 3191393a41..80dcba1cf4 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1504,6 +1504,10 @@ def test_default_values_are_deeply_dupped assert_not_equal Post.new.hash, Post.new.hash end + test "records of different classes have different hashes" do + assert_not_equal Post.new(id: 1).hash, Developer.new(id: 1).hash + end + test "resetting column information doesn't remove attribute methods" do topic = topics(:first)