Skip to content

Commit d592ea3

Browse files
committed
wrap and cache columns for typecasting
1 parent dd1eb78 commit d592ea3

3 files changed

Lines changed: 30 additions & 5 deletions

File tree

activerecord/lib/active_record/attribute_methods/serialization.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@ module Serialization
1010
self.serialized_attributes = {}
1111
end
1212

13+
class Type # :nodoc:
14+
def initialize(column)
15+
@column = column
16+
end
17+
18+
def type_cast(value)
19+
value.unserialized_value
20+
end
21+
end
22+
1323
class Attribute < Struct.new(:coder, :value, :state)
1424
def unserialized_value
1525
state == :serialized ? unserialize : value

activerecord/lib/active_record/core.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ def relation #:nodoc:
165165
# User.new({ :first_name => 'Jamie', :is_admin => true }, :without_protection => true)
166166
def initialize(attributes = nil, options = {})
167167
@attributes = self.class.initialize_attributes(self.class.column_defaults.dup)
168-
@columns_hash = self.class.columns_hash.dup
168+
@columns_hash = self.class.column_types.dup
169169

170170
init_internals
171171

@@ -191,7 +191,7 @@ def initialize(attributes = nil, options = {})
191191
# post.title # => 'hello world'
192192
def init_with(coder)
193193
@attributes = self.class.initialize_attributes(coder['attributes'])
194-
@columns_hash = self.class.columns_hash.merge(coder['column_types'] || {})
194+
@columns_hash = self.class.column_types.merge(coder['column_types'] || {})
195195

196196

197197
init_internals

activerecord/lib/active_record/model_schema.rb

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,14 @@ def columns_hash
206206
@columns_hash ||= Hash[columns.map { |c| [c.name, c] }]
207207
end
208208

209+
def column_types
210+
@column_types ||= columns_hash.dup.tap { |x|
211+
serialized_attributes.keys.each do |key|
212+
x[key] = AttributeMethods::Serialization::Type.new(x[key])
213+
end
214+
}
215+
end
216+
209217
# Returns a hash where the keys are column names and the values are
210218
# default values when instantiating the AR object for this table.
211219
def column_defaults
@@ -268,9 +276,16 @@ def reset_column_information
268276
undefine_attribute_methods
269277
connection.schema_cache.clear_table_cache!(table_name) if table_exists?
270278

271-
@column_names = @content_columns = @column_defaults = @columns = @columns_hash = nil
272-
@dynamic_methods_hash = @inheritance_column = nil
273-
@arel_engine = @relation = nil
279+
@arel_engine = nil
280+
@column_defaults = nil
281+
@column_names = nil
282+
@columns = nil
283+
@columns_hash = nil
284+
@column_types = nil
285+
@content_columns = nil
286+
@dynamic_methods_hash = nil
287+
@inheritance_column = nil
288+
@relation = nil
274289
end
275290

276291
def clear_cache! # :nodoc:

0 commit comments

Comments
 (0)