aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record
diff options
context:
space:
mode:
authorJosh Goodall <joshua@qutonic.com>2013-07-15 11:55:24 +1000
committerGenadi Samokovarov <gsamokovarov@gmail.com>2014-02-17 00:40:16 +0200
commitda3fec2ea3a6a13635500a667c105280c5357c14 (patch)
treece2bea6364532c0c7126a8c39bb67af219abe68e /activerecord/lib/active_record
parent3e3ed1ede51f4d2f7f1d30b3754072b1121d5394 (diff)
downloadrails-da3fec2ea3a6a13635500a667c105280c5357c14.tar.gz
rails-da3fec2ea3a6a13635500a667c105280c5357c14.tar.bz2
rails-da3fec2ea3a6a13635500a667c105280c5357c14.zip
Resolve encoding issues with arrays of hstore (bug 11135).
We didn't have enough encoding for the wire protocol to store an array of hstore types. So, further encode any hstore that is an array member. Whilst we're here, ensure it's an HashWithIndifferentAccess being returned, to be consistent with other serialized forms, and add testing for arrays of hstore. So now the following migration: enable_extension "hstore" create_table :servers do |t| t.string :name t.hstore :interfaces, array: true end produces a model that can used like this, to store an array of hashes: server = Server.create(name: "server01", interfaces: [ { name: "bge0", ipv4: "192.0.2.2", state: "up" }, { name: "de0", state: "disabled", by: "misha" }, { name: "fe0", state: "up" }, ]) More at http://inopinatus.org/2013/07/12/using-arrays-of-hstore-with-rails-4/
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/cast.rb12
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb2
2 files changed, 7 insertions, 7 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb b/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb
index 35ce881302..3a3b500b1f 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb
@@ -35,11 +35,11 @@ module ActiveRecord
end
end
- def hstore_to_string(object)
+ def hstore_to_string(object, array_member = false)
if Hash === object
- object.map { |k,v|
- "#{escape_hstore(k)}=>#{escape_hstore(v)}"
- }.join ','
+ string = object.map { |k, v| "#{escape_hstore(k)}=>#{escape_hstore(v)}" }.join(',')
+ string = escape_hstore(string) if array_member
+ string
else
object
end
@@ -49,10 +49,10 @@ module ActiveRecord
if string.nil?
nil
elsif String === string
- Hash[string.scan(HstorePair).map { |k,v|
+ Hash[string.scan(HstorePair).map { |k, v|
v = v.upcase == 'NULL' ? nil : v.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1')
k = k.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1')
- [k,v]
+ [k, v]
}]
else
string
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
index c1f978a081..210172cf32 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
@@ -121,7 +121,7 @@ module ActiveRecord
end
when Hash
case column.sql_type
- when 'hstore' then PostgreSQLColumn.hstore_to_string(value)
+ when 'hstore' then PostgreSQLColumn.hstore_to_string(value, array_member)
when 'json' then PostgreSQLColumn.json_to_string(value)
else super(value, column)
end