diff options
author | Jon Moss <me@jonathanmoss.me> | 2016-11-15 16:14:15 -0500 |
---|---|---|
committer | Jon Moss <me@jonathanmoss.me> | 2016-11-15 16:42:44 -0500 |
commit | 0a8b212db76441df29a572580f1dab596d28d73d (patch) | |
tree | 501f733bbc3ad2929c308add2ccd17a19f3092c7 | |
parent | 6e692e6e5bb90fbaf1524429139daa9bd1c4f990 (diff) | |
download | rails-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.md | 7 | ||||
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore.rb | 2 | ||||
-rw-r--r-- | activerecord/test/cases/adapters/postgresql/hstore_test.rb | 10 |
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 |