diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2014-06-17 22:59:12 -0300 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2014-06-17 22:59:12 -0300 |
commit | bdc39899ebb2a17e91cfde1803da3d1170531f04 (patch) | |
tree | e9bafb7f42fc28bbc1956ce61c17b14aaec935da | |
parent | 84a13e019e93efaa8994b3f8303d635a7702dbce (diff) | |
parent | 455c692b047ad1af1670b5377a1c4313ad0d1228 (diff) | |
download | rails-bdc39899ebb2a17e91cfde1803da3d1170531f04.tar.gz rails-bdc39899ebb2a17e91cfde1803da3d1170531f04.tar.bz2 rails-bdc39899ebb2a17e91cfde1803da3d1170531f04.zip |
Merge pull request #15790 from sgrif/sg-mutable-points
Detect in-place changes on point types
3 files changed, 31 insertions, 3 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb b/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb index acc4cdc9e8..a865c5c310 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb @@ -3,7 +3,11 @@ module ActiveRecord module PostgreSQL module Cast # :nodoc: def point_to_string(point) # :nodoc: - "(#{point[0]},#{point[1]})" + "(#{number_for_point(point[0])},#{number_for_point(point[1])})" + end + + def number_for_point(number) + number.to_s.gsub(/\.0$/, '') end def hstore_to_string(object, array_member = false) # :nodoc: diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/point.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/point.rb index 9007bfb178..86277c5542 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/point.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/point.rb @@ -3,20 +3,33 @@ module ActiveRecord module PostgreSQL module OID # :nodoc: class Point < Type::Value + include Type::Mutable + def type :point end def type_cast(value) - if ::String === value + case value + when ::String if value[0] == '(' && value[-1] == ')' value = value[1...-1] end - value.split(',').map{ |v| Float(v) } + type_cast(value.split(',')) + when ::Array + value.map { |v| Float(v) } else value end end + + def type_cast_for_database(value) + if value.is_a?(::Array) + PostgreSQLColumn.point_to_string(value) + else + super + end + end end end end diff --git a/activerecord/test/cases/adapters/postgresql/geometric_test.rb b/activerecord/test/cases/adapters/postgresql/geometric_test.rb index 2f106ee664..aa737617c4 100644 --- a/activerecord/test/cases/adapters/postgresql/geometric_test.rb +++ b/activerecord/test/cases/adapters/postgresql/geometric_test.rb @@ -61,4 +61,15 @@ class PostgresqlPointTest < ActiveRecord::TestCase assert record.reload assert_equal [1.1, 2.2], record.x end + + def test_mutation + p = PostgresqlPoint.create! x: [10, 20] + + p.x[1] = 25 + p.save! + p.reload + + assert_equal [10.0, 25.0], p.x + assert_not p.changed? + end end |