aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib')
-rw-r--r--activerecord/lib/active_record/attribute_methods/serialization.rb26
-rw-r--r--activerecord/lib/active_record/connection_adapters/column.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/column.rb4
-rw-r--r--activerecord/lib/active_record/model_schema.rb9
-rw-r--r--activerecord/lib/active_record/properties.rb10
-rw-r--r--activerecord/lib/active_record/type.rb1
-rw-r--r--activerecord/lib/active_record/type/serialized.rb28
-rw-r--r--activerecord/lib/active_record/type/value.rb4
8 files changed, 50 insertions, 38 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb
index 47c6f94ba7..e8c27cb8b8 100644
--- a/activerecord/lib/active_record/attribute_methods/serialization.rb
+++ b/activerecord/lib/active_record/attribute_methods/serialization.rb
@@ -58,32 +58,18 @@ module ActiveRecord
Coders::YAMLColumn.new(class_name_or_coder)
end
+ type = columns_hash[attr_name.to_s].cast_type
+ if type.serialized?
+ type = type.subtype
+ end
+ property attr_name, ActiveRecord::Type::Serialized.new(type)
+
# merge new serialized attribute and create new hash to ensure that each class in inheritance hierarchy
# has its own hash of own serialized attributes
self.serialized_attributes = serialized_attributes.merge(attr_name.to_s => coder)
end
end
- class Type # :nodoc:
- delegate :type, :type_cast_for_database, to: :@column
-
- def initialize(column)
- @column = column
- end
-
- def type_cast(value)
- if value.state == :serialized
- value.unserialized_value @column.type_cast value.value
- else
- value.unserialized_value
- end
- end
-
- def accessor
- ActiveRecord::Store::IndifferentHashAccessor
- end
- end
-
class Attribute < Struct.new(:coder, :value, :state) # :nodoc:
def unserialized_value(v = value)
state == :serialized ? unserialize(v) : value
diff --git a/activerecord/lib/active_record/connection_adapters/column.rb b/activerecord/lib/active_record/connection_adapters/column.rb
index a62617ab47..42650e332d 100644
--- a/activerecord/lib/active_record/connection_adapters/column.rb
+++ b/activerecord/lib/active_record/connection_adapters/column.rb
@@ -15,8 +15,10 @@ module ActiveRecord
attr_reader :name, :default, :cast_type, :null, :sql_type, :default_function
- delegate :type, :precision, :scale, :limit, :klass, :text?, :number?, :binary?,
- :type_cast, :type_cast_for_write, :type_cast_for_database, to: :cast_type
+ delegate :type, :precision, :scale, :limit, :klass, :accessor,
+ :text?, :number?, :binary?, :serialized?,
+ :type_cast, :type_cast_for_write, :type_cast_for_database,
+ to: :cast_type
# Instantiates a new column in the table.
#
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/column.rb b/activerecord/lib/active_record/connection_adapters/postgresql/column.rb
index 9a5e2d05ef..a579746815 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/column.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/column.rb
@@ -35,10 +35,6 @@ module ActiveRecord
end
end
# :startdoc:
-
- def accessor
- cast_type.accessor
- end
end
end
end
diff --git a/activerecord/lib/active_record/model_schema.rb b/activerecord/lib/active_record/model_schema.rb
index a4e10ed2e7..ad6428d8a8 100644
--- a/activerecord/lib/active_record/model_schema.rb
+++ b/activerecord/lib/active_record/model_schema.rb
@@ -224,14 +224,6 @@ module ActiveRecord
def decorate_columns(columns_hash) # :nodoc:
return if columns_hash.empty?
- @serialized_column_names ||= self.columns_hash.keys.find_all do |name|
- serialized_attributes.key?(name)
- end
-
- @serialized_column_names.each do |name|
- columns_hash[name] = AttributeMethods::Serialization::Type.new(columns_hash[name])
- end
-
@time_zone_column_names ||= self.columns_hash.find_all do |name, col|
create_time_zone_conversion_attribute?(name, col)
end.map!(&:first)
@@ -299,7 +291,6 @@ module ActiveRecord
@dynamic_methods_hash = nil
@inheritance_column = nil unless defined?(@explicit_inheritance_column) && @explicit_inheritance_column
@relation = nil
- @serialized_column_names = nil
@time_zone_column_names = nil
@cached_time_zone = nil
end
diff --git a/activerecord/lib/active_record/properties.rb b/activerecord/lib/active_record/properties.rb
index cc1e8b45c1..7fe59ccce4 100644
--- a/activerecord/lib/active_record/properties.rb
+++ b/activerecord/lib/active_record/properties.rb
@@ -64,6 +64,7 @@ module ActiveRecord
# store_listing.price_in_cents # => 1000
def property(name, cast_type)
name = name.to_s
+ clear_properties_cache
# Assign a new hash to ensure that subclasses do not share a hash
self.user_provided_columns = user_provided_columns.merge(name => connection.new_column(name, nil, cast_type))
end
@@ -80,9 +81,7 @@ module ActiveRecord
def reset_column_information # :nodoc:
super
-
- @columns = nil
- @columns_hash = nil
+ clear_properties_cache
end
private
@@ -97,6 +96,11 @@ module ActiveRecord
existing_columns + new_columns
end
+
+ def clear_properties_cache
+ @columns = nil
+ @columns_hash = nil
+ end
end
end
end
diff --git a/activerecord/lib/active_record/type.rb b/activerecord/lib/active_record/type.rb
index 2c26477201..e9b827886a 100644
--- a/activerecord/lib/active_record/type.rb
+++ b/activerecord/lib/active_record/type.rb
@@ -10,6 +10,7 @@ require 'active_record/type/decimal'
require 'active_record/type/decimal_without_scale'
require 'active_record/type/float'
require 'active_record/type/integer'
+require 'active_record/type/serialized'
require 'active_record/type/string'
require 'active_record/type/text'
require 'active_record/type/time'
diff --git a/activerecord/lib/active_record/type/serialized.rb b/activerecord/lib/active_record/type/serialized.rb
new file mode 100644
index 0000000000..cc7513ca2a
--- /dev/null
+++ b/activerecord/lib/active_record/type/serialized.rb
@@ -0,0 +1,28 @@
+module ActiveRecord
+ module Type
+ class Serialized < SimpleDelegator # :nodoc:
+ attr_reader :subtype
+
+ def initialize(subtype)
+ @subtype = subtype
+ super
+ end
+
+ def type_cast(value)
+ if value.respond_to?(:unserialized_value)
+ value.unserialized_value(super(value.value))
+ else
+ super
+ end
+ end
+
+ def serialized?
+ true
+ end
+
+ def accessor
+ ActiveRecord::Store::IndifferentHashAccessor
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/type/value.rb b/activerecord/lib/active_record/type/value.rb
index 72d27197d5..a5493be8f2 100644
--- a/activerecord/lib/active_record/type/value.rb
+++ b/activerecord/lib/active_record/type/value.rb
@@ -43,6 +43,10 @@ module ActiveRecord
false
end
+ def serialized?
+ false
+ end
+
def klass
::Object
end