aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2012-02-03 14:34:53 -0800
committerAaron Patterson <aaron.patterson@gmail.com>2012-02-07 13:51:53 -0800
commitd592ea3b02c7e0952b87b876ad92bd1b453543c8 (patch)
treeff7bde9d731bb174e367357b8d1b7d667c1b2de7
parentdd1eb78d767d3272f951a240a171b841a5ebd356 (diff)
downloadrails-d592ea3b02c7e0952b87b876ad92bd1b453543c8.tar.gz
rails-d592ea3b02c7e0952b87b876ad92bd1b453543c8.tar.bz2
rails-d592ea3b02c7e0952b87b876ad92bd1b453543c8.zip
wrap and cache columns for typecasting
-rw-r--r--activerecord/lib/active_record/attribute_methods/serialization.rb10
-rw-r--r--activerecord/lib/active_record/core.rb4
-rw-r--r--activerecord/lib/active_record/model_schema.rb21
3 files changed, 30 insertions, 5 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb
index 38e7bf77ef..3bc749dabf 100644
--- a/activerecord/lib/active_record/attribute_methods/serialization.rb
+++ b/activerecord/lib/active_record/attribute_methods/serialization.rb
@@ -10,6 +10,16 @@ module ActiveRecord
self.serialized_attributes = {}
end
+ class Type # :nodoc:
+ def initialize(column)
+ @column = column
+ end
+
+ def type_cast(value)
+ value.unserialized_value
+ end
+ end
+
class Attribute < Struct.new(:coder, :value, :state)
def unserialized_value
state == :serialized ? unserialize : value
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index 74403f9e35..28f52bd270 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -165,7 +165,7 @@ module ActiveRecord
# User.new({ :first_name => 'Jamie', :is_admin => true }, :without_protection => true)
def initialize(attributes = nil, options = {})
@attributes = self.class.initialize_attributes(self.class.column_defaults.dup)
- @columns_hash = self.class.columns_hash.dup
+ @columns_hash = self.class.column_types.dup
init_internals
@@ -191,7 +191,7 @@ module ActiveRecord
# post.title # => 'hello world'
def init_with(coder)
@attributes = self.class.initialize_attributes(coder['attributes'])
- @columns_hash = self.class.columns_hash.merge(coder['column_types'] || {})
+ @columns_hash = self.class.column_types.merge(coder['column_types'] || {})
init_internals
diff --git a/activerecord/lib/active_record/model_schema.rb b/activerecord/lib/active_record/model_schema.rb
index 61f82af0c3..5486e192e4 100644
--- a/activerecord/lib/active_record/model_schema.rb
+++ b/activerecord/lib/active_record/model_schema.rb
@@ -206,6 +206,14 @@ 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])
+ end
+ }
+ end
+
# Returns a hash where the keys are column names and the values are
# default values when instantiating the AR object for this table.
def column_defaults
@@ -268,9 +276,16 @@ module ActiveRecord
undefine_attribute_methods
connection.schema_cache.clear_table_cache!(table_name) if table_exists?
- @column_names = @content_columns = @column_defaults = @columns = @columns_hash = nil
- @dynamic_methods_hash = @inheritance_column = nil
- @arel_engine = @relation = nil
+ @arel_engine = nil
+ @column_defaults = nil
+ @column_names = nil
+ @columns = nil
+ @columns_hash = nil
+ @column_types = nil
+ @content_columns = nil
+ @dynamic_methods_hash = nil
+ @inheritance_column = nil
+ @relation = nil
end
def clear_cache! # :nodoc: