aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Moss <me@jonathanmoss.me>2016-11-15 16:14:15 -0500
committerJon Moss <me@jonathanmoss.me>2016-11-15 16:42:44 -0500
commit0a8b212db76441df29a572580f1dab596d28d73d (patch)
tree501f733bbc3ad2929c308add2ccd17a19f3092c7
parent6e692e6e5bb90fbaf1524429139daa9bd1c4f990 (diff)
downloadrails-0a8b212db76441df29a572580f1dab596d28d73d.tar.gz
rails-0a8b212db76441df29a572580f1dab596d28d73d.tar.bz2
rails-0a8b212db76441df29a572580f1dab596d28d73d.zip
Support AC::Parameters for PG HStore
As reported via #26904, there is a regression in how values for Postgres' HStore column type are being processed, beginning in Rails 5. Currently, the way that Active Record checks whether or not values need to be serialized and put into the correct storage format is whether or not it is a `Hash` object. Since `ActionController::Parameters` no longer inherits from `Hash` in Rails 5, this conditional now returns false. To remedy this, we are now checking to see whether the `value` parameters being passed in responds to a certain method, and then calling the `serialize` method, except this time with a real Hash object. Keeping things DRY! Fixes #26904.
-rw-r--r--activerecord/CHANGELOG.md7
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/hstore_test.rb10
3 files changed, 19 insertions, 0 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 8efefe9b2e..7f4be54dbb 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,10 @@
+* Allow `ActionController::Parameters`-like objects to be passed as
+ values for Postgres HStore columns.
+
+ Fixes #26904.
+
+ *Jon Moss*
+
* Added `stat` method to `ActiveRecord::ConnectionAdapters::ConnectionPool`
Example:
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 a74a044a3a..d629ebca91 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb
@@ -24,6 +24,8 @@ module ActiveRecord
def serialize(value)
if value.is_a?(::Hash)
value.map { |k, v| "#{escape_hstore(k)}=>#{escape_hstore(v)}" }.join(", ")
+ elsif value.respond_to?(:to_unsafe_h)
+ serialize(value.to_unsafe_h)
else
value
end
diff --git a/activerecord/test/cases/adapters/postgresql/hstore_test.rb b/activerecord/test/cases/adapters/postgresql/hstore_test.rb
index c9982d3705..1f35300739 100644
--- a/activerecord/test/cases/adapters/postgresql/hstore_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/hstore_test.rb
@@ -10,6 +10,12 @@ if ActiveRecord::Base.connection.supports_extensions?
store_accessor :settings, :language, :timezone
end
+ class FakeParameters
+ def to_unsafe_h
+ { "hi" => "hi" }
+ end
+ end
+
def setup
@connection = ActiveRecord::Base.connection
@@ -321,6 +327,10 @@ if ActiveRecord::Base.connection.supports_extensions?
assert_match %r[t\.hstore "tags",\s+default: {}], output
end
+ def test_supports_to_unsafe_h_values
+ assert_equal("\"hi\"=>\"hi\"", @type.serialize(FakeParameters.new))
+ end
+
private
def assert_array_cycle(array)
# test creation