Skip to content

Instantly share code, notes, and snippets.

@senny
Last active August 29, 2015 14:01
Show Gist options
  • Save senny/0362bd0941b20b225a1c to your computer and use it in GitHub Desktop.
Save senny/0362bd0941b20b225a1c to your computer and use it in GitHub Desktop.
4-1-stable backportable patch of https://github.com/rails/rails/issues/15369
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index c39240d..a8d3723 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,10 @@
+* Keep PostgreSQL `hstore` and `json` attributes as `Hash` in `@attributes`.
+ Fixes duplication in combination with `store_accessor`.
+
+ Fixes #15369.
+
+ *Yves Senn*
+
* `rake railties:install:migrations` respects the order of railties.
*Arun Agrawal*
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
index 7878c8f..947ac05 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
@@ -231,7 +231,10 @@ module ActiveRecord
class Hstore < Type
def type_cast_for_write(value)
- ConnectionAdapters::PostgreSQLColumn.hstore_to_string value
+ # roundtrip to ensure uniform uniform types
+ # TODO: This is not an efficient solution.
+ stringified = ConnectionAdapters::PostgreSQLColumn.hstore_to_string(value)
+ type_cast(stringified)
end
def type_cast(value)
@@ -255,7 +258,10 @@ module ActiveRecord
class Json < Type
def type_cast_for_write(value)
- ConnectionAdapters::PostgreSQLColumn.json_to_string value
+ # roundtrip to ensure uniform uniform types
+ # TODO: This is not an efficient solution.
+ stringified = ConnectionAdapters::PostgreSQLColumn.json_to_string(value)
+ type_cast(stringified)
end
def type_cast(value)
diff --git a/activerecord/test/cases/adapters/postgresql/hstore_test.rb b/activerecord/test/cases/adapters/postgresql/hstore_test.rb
index f250243..b76fc45 100644
--- a/activerecord/test/cases/adapters/postgresql/hstore_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/hstore_test.rb
@@ -126,6 +126,16 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase
assert_equal "GMT", x.timezone
end
+ def test_duplication_with_store_accessors
+ x = Hstore.new(language: "fr", timezone: "GMT")
+ assert_equal "fr", x.language
+ assert_equal "GMT", x.timezone
+
+ y = x.dup
+ assert_equal "fr", y.language
+ assert_equal "GMT", y.timezone
+ end
+
def test_gen1
assert_equal(%q(" "=>""), @column.class.hstore_to_string({' '=>''}))
end
diff --git a/activerecord/test/cases/adapters/postgresql/json_test.rb b/activerecord/test/cases/adapters/postgresql/json_test.rb
index 3daef39..fa98f81 100644
--- a/activerecord/test/cases/adapters/postgresql/json_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/json_test.rb
@@ -122,6 +122,14 @@ class PostgresqlJSONTest < ActiveRecord::TestCase
assert_equal "640×1136", x.resolution
end
+ def test_duplication_with_store_accessors
+ x = JsonDataType.new(resolution: "320×480")
+ assert_equal "320×480", x.resolution
+
+ y = x.dup
+ assert_equal "320×480", y.resolution
+ end
+
def test_update_all
json = JsonDataType.create! payload: { "one" => "two" }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment