mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Extract attribute serialization code into a separate module
This commit is contained in:
parent
61489dc684
commit
f4853dc174
4 changed files with 49 additions and 28 deletions
|
@ -92,6 +92,7 @@ module ActiveRecord
|
|||
autoload :Read
|
||||
autoload :TimeZoneConversion
|
||||
autoload :Write
|
||||
autoload :Serialization
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -34,22 +34,12 @@ module ActiveRecord
|
|||
|
||||
protected
|
||||
def define_method_attribute(attr_name)
|
||||
if serialized_attributes.include?(attr_name)
|
||||
define_read_method_for_serialized_attribute(attr_name)
|
||||
else
|
||||
define_read_method(attr_name, attr_name, columns_hash[attr_name])
|
||||
end
|
||||
define_read_method(attr_name, attr_name, columns_hash[attr_name])
|
||||
end
|
||||
|
||||
private
|
||||
def cacheable_column?(column)
|
||||
serialized_attributes.include?(column.name) || attribute_types_cached_by_default.include?(column.type)
|
||||
end
|
||||
|
||||
# Define read method for serialized attribute.
|
||||
def define_read_method_for_serialized_attribute(attr_name)
|
||||
access_code = "@attributes_cache['#{attr_name}'] ||= @attributes['#{attr_name}']"
|
||||
generated_attribute_methods.module_eval("def _#{attr_name}; #{access_code}; end; alias #{attr_name} _#{attr_name}", __FILE__, __LINE__)
|
||||
attribute_types_cached_by_default.include?(column.type)
|
||||
end
|
||||
|
||||
# Define an attribute reader method. Cope with nil column.
|
||||
|
@ -107,28 +97,15 @@ module ActiveRecord
|
|||
value = @attributes[attr_name]
|
||||
unless value.nil?
|
||||
if column = column_for_attribute(attr_name)
|
||||
if unserializable_attribute?(attr_name, column)
|
||||
unserialize_attribute(attr_name)
|
||||
else
|
||||
column.type_cast(value)
|
||||
end
|
||||
type_cast_attribute(column, value)
|
||||
else
|
||||
value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Returns true if the attribute is of a text column and marked for serialization.
|
||||
def unserializable_attribute?(attr_name, column)
|
||||
column.text? && self.class.serialized_attributes.include?(attr_name)
|
||||
end
|
||||
|
||||
# Returns the unserialized object of the attribute.
|
||||
def unserialize_attribute(attr_name)
|
||||
coder = self.class.serialized_attributes[attr_name]
|
||||
unserialized_object = coder.load(@attributes[attr_name])
|
||||
|
||||
@attributes.frozen? ? unserialized_object : @attributes[attr_name] = unserialized_object
|
||||
def type_cast_attribute(column, value) #:nodoc:
|
||||
column.type_cast(value)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
module ActiveRecord
|
||||
module AttributeMethods
|
||||
module Serialization
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
module ClassMethods
|
||||
def define_method_attribute(attr_name)
|
||||
if serialized_attributes.include?(attr_name)
|
||||
generated_attribute_methods.module_eval(<<-CODE, __FILE__, __LINE__)
|
||||
def _#{attr_name}
|
||||
@attributes_cache['#{attr_name}'] ||= @attributes['#{attr_name}']
|
||||
end
|
||||
alias #{attr_name} _#{attr_name}
|
||||
CODE
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def cacheable_column?(column)
|
||||
serialized_attributes.include?(column.name) || super
|
||||
end
|
||||
end
|
||||
|
||||
def type_cast_attribute(column, value)
|
||||
coder = self.class.serialized_attributes[column.name]
|
||||
|
||||
if column.text? && coder
|
||||
unserialized_object = coder.load(@attributes[column.name])
|
||||
|
||||
if @attributes.frozen?
|
||||
unserialized_object
|
||||
else
|
||||
@attributes[column.name] = unserialized_object
|
||||
end
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2219,6 +2219,7 @@ MSG
|
|||
include AttributeMethods::PrimaryKey
|
||||
include AttributeMethods::TimeZoneConversion
|
||||
include AttributeMethods::Dirty
|
||||
include AttributeMethods::Serialization
|
||||
include ActiveModel::MassAssignmentSecurity
|
||||
include Callbacks, ActiveModel::Observing, Timestamp
|
||||
include Associations, NamedScope
|
||||
|
|
Loading…
Reference in a new issue