aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorSean Griffin <sean@seantheprogrammer.com>2017-01-03 16:12:46 -0500
committerGitHub <noreply@github.com>2017-01-03 16:12:46 -0500
commit95962c4fe0d09976e90cf7e179a72085a29812a7 (patch)
treec9d5d943dd37d2273405d3c9cbd3d3278a04c523 /activerecord
parent769b25af588d87e4570c6b454990118ab432a3aa (diff)
parent8ded825bc29338d1a2ae7c3a2119cfa301008f85 (diff)
downloadrails-95962c4fe0d09976e90cf7e179a72085a29812a7.tar.gz
rails-95962c4fe0d09976e90cf7e179a72085a29812a7.tar.bz2
rails-95962c4fe0d09976e90cf7e179a72085a29812a7.zip
Merge pull request #27517 from maclover7/jm-fix-27502
Compare deserialized values for `PostgreSQL::OID::Hstore` types
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG.md7
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb8
-rw-r--r--activerecord/test/cases/adapters/postgresql/hstore_test.rb19
3 files changed, 34 insertions, 0 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 00d1a7a623..743a38b087 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,10 @@
+* Compare deserialized values for `PostgreSQL::OID::Hstore` types when
+ calling `ActiveRecord::Dirty#changed_in_place?`
+
+ Fixes #27502.
+
+ *Jon Moss*
+
* Raise `ArgumentError` when passing an `ActiveRecord::Base` instance to `.find`
and `.exists?`.
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb
index d629ebca91..49dd4fc73f 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb
@@ -35,6 +35,14 @@ module ActiveRecord
ActiveRecord::Store::StringKeyedHashAccessor
end
+ # Will compare the Hash equivalents of +raw_old_value+ and +new_value+.
+ # By comparing hashes, this avoids an edge case where the order of
+ # the keys change between the two hashes, and they would not be marked
+ # as equal.
+ def changed_in_place?(raw_old_value, new_value)
+ deserialize(raw_old_value) != new_value
+ end
+
private
HstorePair = begin
diff --git a/activerecord/test/cases/adapters/postgresql/hstore_test.rb b/activerecord/test/cases/adapters/postgresql/hstore_test.rb
index 1f35300739..f9cce10fb8 100644
--- a/activerecord/test/cases/adapters/postgresql/hstore_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/hstore_test.rb
@@ -171,6 +171,25 @@ if ActiveRecord::Base.connection.supports_extensions?
assert_not hstore.changed?
end
+ def test_dirty_from_user_equal
+ settings = { "alongkey" => "anything", "key" => "value" }
+ hstore = Hstore.create!(settings: settings)
+
+ hstore.settings = { "key" => "value", "alongkey" => "anything" }
+ assert_equal settings, hstore.settings
+ refute hstore.changed?
+ end
+
+ def test_hstore_dirty_from_database_equal
+ settings = { "alongkey" => "anything", "key" => "value" }
+ hstore = Hstore.create!(settings: settings)
+ hstore.reload
+
+ assert_equal settings, hstore.settings
+ hstore.settings = settings
+ refute hstore.changed?
+ end
+
def test_gen1
assert_equal('" "=>""', @type.serialize(" " => ""))
end