aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorSean Griffin <sean@thoughtbot.com>2014-06-13 07:16:15 -0600
committerSean Griffin <sean@thoughtbot.com>2014-06-13 07:16:47 -0600
commitd569d0baad8b4c30b2144de2af1c98f2e91a2099 (patch)
tree69d206a7bba8e39e1510b91fe5e795fd12929c1e /activerecord
parent9a0c2e5c626cfbde527013bd0cfcec682baa48fa (diff)
downloadrails-d569d0baad8b4c30b2144de2af1c98f2e91a2099.tar.gz
rails-d569d0baad8b4c30b2144de2af1c98f2e91a2099.tar.bz2
rails-d569d0baad8b4c30b2144de2af1c98f2e91a2099.zip
PG arrays should type cast user input
We guarantee that `model.value` does not change after `model.save && model.reload`. This requires type casting user input for non-string types.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb12
-rw-r--r--activerecord/test/cases/adapters/postgresql/array_test.rb9
2 files changed, 15 insertions, 6 deletions
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 87817fe8d1..4e7d472d97 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb
@@ -12,12 +12,16 @@ module ActiveRecord
def type_cast_from_database(value)
if value.is_a?(::String)
- type_cast_array(parse_pg_array(value))
+ type_cast_array(parse_pg_array(value), :type_cast_from_database)
else
super
end
end
+ def type_cast_from_user(value)
+ type_cast_array(value, :type_cast_from_user)
+ end
+
# Loads pg_array_parser if available. String parsing can be
# performed quicker by a native extension, which will not create
# a large amount of Ruby objects that will need to be garbage
@@ -32,11 +36,11 @@ module ActiveRecord
private
- def type_cast_array(value)
+ def type_cast_array(value, method)
if value.is_a?(::Array)
- value.map { |item| type_cast_array(item) }
+ value.map { |item| type_cast_array(item, method) }
else
- @subtype.type_cast_from_database(value)
+ @subtype.public_send(method, value)
end
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/array_test.rb b/activerecord/test/cases/adapters/postgresql/array_test.rb
index 66750deb68..0b1e3295cc 100644
--- a/activerecord/test/cases/adapters/postgresql/array_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/array_test.rb
@@ -97,8 +97,13 @@ class PostgresqlArrayTest < ActiveRecord::TestCase
def test_type_cast_integers
x = PgArray.new(ratings: ['1', '2'])
- assert x.save!
- assert_equal(['1', '2'], x.ratings)
+
+ assert_equal([1, 2], x.ratings)
+
+ x.save!
+ x.reload
+
+ assert_equal([1, 2], x.ratings)
end
def test_select_with_strings