aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorCarlos Antonio da Silva <carlosantoniodasilva@gmail.com>2013-12-19 17:39:20 -0200
committerCarlos Antonio da Silva <carlosantoniodasilva@gmail.com>2013-12-23 16:26:15 -0200
commit56510091fb8d178ec7c2391bed9fbdb9e3a54287 (patch)
treea4827bf9d0539ce16cfae2497679d3841a64b64d /activerecord
parent618d5317d3ce3d40a22293149f79ff9843bbdb35 (diff)
downloadrails-56510091fb8d178ec7c2391bed9fbdb9e3a54287.tar.gz
rails-56510091fb8d178ec7c2391bed9fbdb9e3a54287.tar.bz2
rails-56510091fb8d178ec7c2391bed9fbdb9e3a54287.zip
Do not consider PG array columns as number or text columns
The code uses these checks in several places to know what to do with a particular column, for instance AR attribute query methods has a branch like this: if column.number? !value.zero? end This should never be true for array columns, since it would be the same as running [].zero?, which results in a NoMethodError exception. Fixing this by ensuring that array columns in PostgreSQL never return true for number?/text? checks. Since most of the array support was based on the postgres_ext lib, it's worth noting it does the same thing for numeric array columns too: https://github.com/dockyard/postgres_ext/blob/v1.0.0/lib/postgres_ext/active_record/connection_adapters/postgres_adapter.rb#L72 This extended the same logic for text columns to ensure consistency.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG.md18
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb10
-rw-r--r--activerecord/test/cases/adapters/postgresql/array_test.rb8
3 files changed, 33 insertions, 3 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 6d130ab4d6..45dfeddba8 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,21 @@
+* Do not consider PostgreSQL array columns as number or text columns.
+
+ The code uses these checks in several places to know what to do with a
+ particular column, for instance AR attribute query methods has a branch
+ like this:
+
+ if column.number?
+ !value.zero?
+ end
+
+ This should never be true for array columns, since it would be the same
+ as running [].zero?, which results in a NoMethodError exception.
+
+ Fixing this by ensuring that array columns in PostgreSQL never return
+ true for number?/text? checks.
+
+ *Carlos Antonio da Silva*
+
* When connecting to a non-existant postgresql database, the error:
`ActiveRecord::NoDatabaseError` will now be raised. When being used with Rails
the error message will include information on how to create a database:
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 95cd69d5ad..11a5eba464 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -46,7 +46,7 @@ module ActiveRecord
# PostgreSQL-specific extensions to column definitions in a table.
class PostgreSQLColumn < Column #:nodoc:
attr_accessor :array
- # Instantiates a new PostgreSQL column definition in a table.
+
def initialize(name, default, oid_type, sql_type = nil, null = true)
@oid_type = oid_type
default_value = self.class.extract_value_from_default(default)
@@ -62,6 +62,14 @@ module ActiveRecord
@default_function = default if has_default_function?(default_value, default)
end
+ def number?
+ !array && super
+ end
+
+ def text?
+ !array && super
+ end
+
# :stopdoc:
class << self
include ConnectionAdapters::PostgreSQLColumn::Cast
diff --git a/activerecord/test/cases/adapters/postgresql/array_test.rb b/activerecord/test/cases/adapters/postgresql/array_test.rb
index 114d5b6cc6..b0870e2256 100644
--- a/activerecord/test/cases/adapters/postgresql/array_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/array_test.rb
@@ -26,6 +26,12 @@ class PostgresqlArrayTest < ActiveRecord::TestCase
def test_column
assert_equal :string, @column.type
assert @column.array
+ assert_not @column.text?
+
+ ratings_column = PgArray.columns_hash['ratings']
+ assert_equal :integer, ratings_column.type
+ assert ratings_column.array
+ assert_not ratings_column.number?
end
def test_change_column_with_array
@@ -50,8 +56,6 @@ class PostgresqlArrayTest < ActiveRecord::TestCase
end
def test_type_cast_array
- assert @column
-
data = '{1,2,3}'
oid_type = @column.instance_variable_get('@oid_type').subtype
# we are getting the instance variable in this test, but in the