diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2012-02-03 15:14:00 -0800 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2012-02-07 14:13:46 -0800 |
commit | 5396fca1e2ab656e460713523efe3a5b1e967d30 (patch) | |
tree | 23e834917a5b694bb9ebcd4ade1998bab3470327 /activerecord | |
parent | 98211755bb8145d2622b46bff9246daa607dafe4 (diff) | |
download | rails-5396fca1e2ab656e460713523efe3a5b1e967d30.tar.gz rails-5396fca1e2ab656e460713523efe3a5b1e967d30.tar.bz2 rails-5396fca1e2ab656e460713523efe3a5b1e967d30.zip |
give each PG type a `type` method and decortate tz attributes
Diffstat (limited to 'activerecord')
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 |