aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYves Senn <yves.senn@gmail.com>2014-03-04 13:14:41 +0100
committerYves Senn <yves.senn@gmail.com>2014-03-04 13:14:41 +0100
commit9ada39f62edad92ef1e754f93b71e452397f53b8 (patch)
treec874d86ca782b8018ce7e161d295cb346156025e
parent7231a135ea53d306b259782cb93d68e633397be5 (diff)
parent5c55aafd38f45ac019573f98438ffdbdc8c580f9 (diff)
downloadrails-9ada39f62edad92ef1e754f93b71e452397f53b8.tar.gz
rails-9ada39f62edad92ef1e754f93b71e452397f53b8.tar.bz2
rails-9ada39f62edad92ef1e754f93b71e452397f53b8.zip
Merge pull request #13244 from kommen/pg_enum_type_map
Add Enum type to postgresql adapter's oids to prevent unknown OID warnings
-rw-r--r--activerecord/CHANGELOG.md5
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb6
-rw-r--r--activerecord/test/cases/adapters/postgresql/enum_test.rb28
4 files changed, 45 insertions, 0 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 654026da4c..3e6758c222 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,8 @@
+* Dynamically register PostgreSQL enum OIDs. This prevents "unknown OID"
+ warnings on enum columns.
+
+ *Dieter Komendera*
+
* `includes` is able to detect the right preloading strategy when string
joins are involved.
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
index e7df073627..697915f3e9 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
@@ -229,6 +229,12 @@ This is not reliable and will be removed in the future.
end
end
+ class Enum < Type
+ def type_cast(value)
+ value.to_s
+ end
+ end
+
class Hstore < Type
def type_cast_for_write(value)
ConnectionAdapters::PostgreSQLColumn.hstore_to_string value
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 9f18fdd3e5..a56ef91d07 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -801,6 +801,12 @@ module ActiveRecord
leaves, nodes = nodes.partition { |row| row['typelem'] == '0' }
arrays, nodes = nodes.partition { |row| row['typinput'] == 'array_in' }
+ # populate the enum types
+ enums, leaves = leaves.partition { |row| row['typinput'] == 'enum_in' }
+ enums.each do |row|
+ type_map[row['oid'].to_i] = OID::Enum.new
+ end
+
# populate the base types
leaves.find_all { |row| OID.registered_type? row['typname'] }.each do |row|
type_map[row['oid'].to_i] = OID::NAMES[row['typname']]
diff --git a/activerecord/test/cases/adapters/postgresql/enum_test.rb b/activerecord/test/cases/adapters/postgresql/enum_test.rb
index bf8dbd6c3f..a9a2901436 100644
--- a/activerecord/test/cases/adapters/postgresql/enum_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/enum_test.rb
@@ -23,6 +23,8 @@ class PostgresqlEnumTest < ActiveRecord::TestCase
t.column :current_mood, :mood
end
end
+ # reload type map after creating the enum type
+ @connection.send(:reload_type_map)
end
def test_enum_mapping
@@ -35,4 +37,30 @@ class PostgresqlEnumTest < ActiveRecord::TestCase
assert_equal "happy", enum.reload.current_mood
end
+
+ def test_invalid_enum_update
+ @connection.execute "INSERT INTO postgresql_enums VALUES (1, 'sad');"
+ enum = PostgresqlEnum.first
+ enum.current_mood = "angry"
+
+ assert_raise ActiveRecord::StatementInvalid do
+ enum.save
+ end
+ end
+
+ def test_no_oid_warning
+ @connection.execute "INSERT INTO postgresql_enums VALUES (1, 'sad');"
+ stderr_output = capture(:stderr) {
+ enum = PostgresqlEnum.first
+ }
+
+ assert stderr_output.blank?
+ end
+
+ def test_enum_type_cast
+ enum = PostgresqlEnum.new
+ enum.current_mood = :happy
+
+ assert_equal "happy", enum.current_mood
+ end
end