aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/attribute_methods/serialization.rb4
-rw-r--r--activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb19
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid.rb32
-rw-r--r--activerecord/lib/active_record/inheritance.rb1
-rw-r--r--activerecord/lib/active_record/model_schema.rb22
5 files changed, 60 insertions, 18 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb
index 3bc749dabf..1fe5d9de20 100644
--- a/activerecord/lib/active_record/attribute_methods/serialization.rb
+++ b/activerecord/lib/active_record/attribute_methods/serialization.rb
@@ -18,6 +18,10 @@ module ActiveRecord
def type_cast(value)
value.unserialized_value
end
+
+ def type
+ @column.type
+ end
end
class Attribute < Struct.new(:coder, :value, :state)
diff --git a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
index 19dcceea88..802add9986 100644
--- a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
+++ b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
@@ -4,6 +4,21 @@ require 'active_support/core_ext/object/inclusion'
module ActiveRecord
module AttributeMethods
module TimeZoneConversion
+ class Type # :nodoc:
+ def initialize(column)
+ @column = column
+ end
+
+ def type_cast(value)
+ value = @column.type_cast(value)
+ value.acts_like?(:time) ? value.in_time_zone : value
+ end
+
+ def type
+ @column.type
+ end
+ end
+
extend ActiveSupport::Concern
included do
@@ -64,7 +79,9 @@ module ActiveRecord
end
def create_time_zone_conversion_attribute?(name, column)
- time_zone_aware_attributes && !self.skip_time_zone_conversion_for_attributes.include?(name.to_sym) && column.type.in?([:datetime, :timestamp])
+ time_zone_aware_attributes &&
+ !self.skip_time_zone_conversion_for_attributes.include?(name.to_sym) &&
+ [:datetime, :timestamp].include?(column.type)
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
index 3216b7709c..a94259a875 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
@@ -11,19 +11,23 @@ module ActiveRecord
end
end
- class Identity
+ class Type
+ def type; end
+ end
+
+ class Identity < Type
def type_cast(value)
value
end
end
- class Bytea
+ class Bytea < Type
def type_cast(value)
PGconn.unescape_bytea value if value
end
end
- class Money
+ class Money < Type
def type_cast(value)
return if value.nil?
@@ -43,7 +47,7 @@ module ActiveRecord
end
end
- class Vector
+ class Vector < Type
attr_reader :delim, :subtype
# +delim+ corresponds to the `typdelim` column in the pg_types
@@ -62,7 +66,7 @@ module ActiveRecord
end
end
- class Integer
+ class Integer < Type
def type_cast(value)
return if value.nil?
@@ -70,7 +74,7 @@ module ActiveRecord
end
end
- class Boolean
+ class Boolean < Type
def type_cast(value)
return if value.nil?
@@ -78,7 +82,9 @@ module ActiveRecord
end
end
- class Timestamp
+ class Timestamp < Type
+ def type; :timestamp; end
+
def type_cast(value)
return if value.nil?
@@ -88,7 +94,9 @@ module ActiveRecord
end
end
- class Date
+ class Date < Type
+ def type; :datetime; end
+
def type_cast(value)
return if value.nil?
@@ -98,7 +106,7 @@ module ActiveRecord
end
end
- class Time
+ class Time < Type
def type_cast(value)
return if value.nil?
@@ -108,7 +116,7 @@ module ActiveRecord
end
end
- class Float
+ class Float < Type
def type_cast(value)
return if value.nil?
@@ -116,7 +124,7 @@ module ActiveRecord
end
end
- class Decimal
+ class Decimal < Type
def type_cast(value)
return if value.nil?
@@ -124,7 +132,7 @@ module ActiveRecord
end
end
- class Hstore
+ class Hstore < Type
def type_cast(value)
return if value.nil?
diff --git a/activerecord/lib/active_record/inheritance.rb b/activerecord/lib/active_record/inheritance.rb
index 1f5b3b2e79..2c766411a0 100644
--- a/activerecord/lib/active_record/inheritance.rb
+++ b/activerecord/lib/active_record/inheritance.rb
@@ -77,6 +77,7 @@ module ActiveRecord
IdentityMap.add(instance)
end
else
+ column_types = sti_class.decorate_columns(column_types)
instance = sti_class.allocate.init_with('attributes' => record,
'column_types' => column_types)
end
diff --git a/activerecord/lib/active_record/model_schema.rb b/activerecord/lib/active_record/model_schema.rb
index 5486e192e4..b8764217d3 100644
--- a/activerecord/lib/active_record/model_schema.rb
+++ b/activerecord/lib/active_record/model_schema.rb
@@ -206,12 +206,24 @@ module ActiveRecord
@columns_hash ||= Hash[columns.map { |c| [c.name, c] }]
end
- def column_types
- @column_types ||= columns_hash.dup.tap { |x|
- serialized_attributes.keys.each do |key|
- x[key] = AttributeMethods::Serialization::Type.new(x[key])
+ def column_types # :nodoc:
+ @column_types ||= decorate_columns(columns_hash.dup)
+ end
+
+ def decorate_columns(columns_hash) # :nodoc:
+ return if columns_hash.empty?
+
+ serialized_attributes.keys.each do |key|
+ columns_hash[key] = AttributeMethods::Serialization::Type.new(columns_hash[key])
+ end
+
+ columns_hash.each do |name, col|
+ if create_time_zone_conversion_attribute?(name, col)
+ columns_hash[name] = AttributeMethods::TimeZoneConversion::Type.new(col)
end
- }
+ end
+
+ columns_hash
end
# Returns a hash where the keys are column names and the values are