From 7ba3a48df5bfdc5e98506bb829f937e03b55a5b3 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Wed, 31 Aug 2016 12:06:30 -0400 Subject: Attempt to maintain encoding for arrays of strings with PG I still think that this is something that should be handled in the pg gem, but it's not going to end up happening there so we'll do it here instead. Once we bump to pg 0.19 we can pass the encoding to the `encode` method instead. This issue occurs because C has no concept of encoding (or strings, really). The bytes that we pass here when sending the value to the database will always be interpreted as whatever encoding the connection is currently configured to use. That means that roundtripping to the database will lose no information However, after assigning we round trip through our type system without hitting the database. The only way that we can do the "correct" thin here would be to actually give a reference to the connection to the array type and have it check the current value of the connection's encoding -- which I'm strongly opposed to. We could also pass in the encoding when it's constructed, but since that can change independently of the type I'm not a huge fan of that either. This feels like a reasonable middle ground, where if we have an array of strings we simply use the encoding of the string we're given. Fixes #26326. --- .../connection_adapters/postgresql/oid/array.rb | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/connection_adapters') diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb index 1a66afb23a..b969503178 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb @@ -33,7 +33,11 @@ module ActiveRecord def serialize(value) if value.is_a?(::Array) - @pg_encoder.encode(type_cast_array(value, :serialize)) + result = @pg_encoder.encode(type_cast_array(value, :serialize)) + if encoding = determine_encoding_of_strings(value) + result.encode!(encoding) + end + result else super end @@ -63,6 +67,13 @@ module ActiveRecord @subtype.public_send(method, value) end end + + def determine_encoding_of_strings(value) + case value + when ::Array then determine_encoding_of_strings(value.first) + when ::String then value.encoding + end + end end end end -- cgit v1.2.3