diff --git a/lib/active_record/attribute_methods.rb b/lib/active_record/attribute_methods.rb index fab16a4..2cab482 100644 --- a/lib/active_record/attribute_methods.rb +++ b/lib/active_record/attribute_methods.rb @@ -70,9 +70,7 @@ module ActiveRecord return if generated_methods? columns_hash.each do |name, column| unless instance_method_already_implemented?(name) - if self.serialized_attributes[name] - define_read_method_for_serialized_attribute(name) - elsif create_time_zone_conversion_attribute?(name, column) + if create_time_zone_conversion_attribute?(name, column) define_read_method_for_time_zone_conversion(name) else define_read_method(name.to_sym, name, column) @@ -157,11 +155,6 @@ module ActiveRecord evaluate_attribute_method attr_name, "def #{symbol}; #{access_code}; end" end - # Define read method for serialized attribute. - def define_read_method_for_serialized_attribute(attr_name) - evaluate_attribute_method attr_name, "def #{attr_name}; unserialize_attribute('#{attr_name}'); end" - end - # Defined for all +datetime+ and +timestamp+ attributes when +time_zone_aware_attributes+ are enabled. # This enhanced read method automatically converts the UTC time stored in the database to the time zone stored in Time.zone. def define_read_method_for_time_zone_conversion(attr_name) @@ -263,11 +256,7 @@ module ActiveRecord attr_name = attr_name.to_s if !(value = @attributes[attr_name]).nil? if column = column_for_attribute(attr_name) - if unserializable_attribute?(attr_name, column) - unserialize_attribute(attr_name) - else - column.type_cast(value) - end + column.type_cast(value) else value end @@ -285,19 +274,6 @@ module ActiveRecord column.text? && self.class.serialized_attributes[attr_name] end - # Returns the unserialized object of the attribute. - def unserialize_attribute(attr_name) - unserialized_object = object_from_yaml(@attributes[attr_name]) - - if unserialized_object.is_a?(self.class.serialized_attributes[attr_name]) || unserialized_object.nil? - @attributes.frozen? ? unserialized_object : @attributes[attr_name] = unserialized_object - else - raise SerializationTypeMismatch, - "#{attr_name} was supposed to be a #{self.class.serialized_attributes[attr_name]}, but was a #{unserialized_object.class.to_s}" - end - end - - # Updates the attribute identified by attr_name with the specified +value+. Empty strings for fixnum and float # columns are turned into +nil+. def write_attribute(attr_name, value) diff --git a/lib/active_record/base.rb b/lib/active_record/base.rb index c393128..e86c864 100755 --- a/lib/active_record/base.rb +++ b/lib/active_record/base.rb @@ -1434,6 +1434,16 @@ module ActiveRecord #:nodoc: else allocate end + + columns_to_deserialize = record.keys.select {|k| serialized_attributes[k]} + columns_to_deserialize.each do |k| + next unless record[k] + deserialized_record = YAML::load(record[k]) + unless deserialized_record.is_a? serialized_attributes[k] || deserialized_record.nil? + raise SerializationTypeMismatch, "#{k} was supposed to be a #{serialized_attributes[k]}, but was a #{deserialized_record.class.to_s}" + end + record[k] = deserialized_record + end object.instance_variable_set("@attributes", record) object.instance_variable_set("@attributes_cache", Hash.new) @@ -2565,7 +2575,10 @@ module ActiveRecord #:nodoc: connection = self.class.connection attribute_names.each do |name| if column = column_for_attribute(name) - quoted[name] = connection.quote(read_attribute(name), column) unless !include_primary_key && column.primary + unless !include_primary_key && column.primary + quoted[name] = connection.quote(read_attribute(name), column) + quoted[name] = connection.quote(read_attribute(name).to_yaml, column) if self.class.serialized_attributes[name] + end end end include_readonly_attributes ? quoted : remove_readonly_attributes(quoted) diff --git a/test/cases/serialization_test.rb b/test/cases/serialization_test.rb index 8841694..300a769 100644 --- a/test/cases/serialization_test.rb +++ b/test/cases/serialization_test.rb @@ -11,11 +11,19 @@ class SerializationTest < ActiveRecord::TestCase :avatar => 'binarydata', :created_at => Time.utc(2006, 8, 1), :awesome => false, - :preferences => { :gem => 'ruby' } + :preferences => { :gem => 'ruby' }, + :biography => <AARON IS A COOL DUDE +EOF } @contact = Contact.new(@contact_attributes) end + + def test_serialized_columns + assert_equal @contact_attributes[:biography], @contact.biography + assert_equal @contact_attributes[:preferences], @contact.preferences + end def test_serialize_should_be_reversible for format in FORMATS diff --git a/test/models/contact.rb b/test/models/contact.rb index dbfa57b..9a5b350 100644 --- a/test/models/contact.rb +++ b/test/models/contact.rb @@ -11,6 +11,8 @@ class Contact < ActiveRecord::Base column :created_at, :datetime column :awesome, :boolean column :preferences, :string + column :biography, :text serialize :preferences + serialize :biography end \ No newline at end of file