From 44ee5581b925cff4c091c0e799b944247e22dff8 Mon Sep 17 00:00:00 2001 From: Les Hill Date: Wed, 14 May 2008 10:42:40 -0400 Subject: [PATCH] Patch for STI subclass serialized bug This patches AR to allow an STI subclass to serialize an attribute that was not serialized in the parent. This may be related to ticket #10815 in Trac, and will not occur when running a rails app in development mode. Patch paired by wes.gibbs@gmail.com and leshill@gmail.com --- .../lib/active_record/attribute_methods.rb | 16 +++++++++------- activerecord/test/cases/serialized_sti_test.rb | 15 +++++++++++++++ activerecord/test/models/droid.rb | 6 ++++++ activerecord/test/schema/schema.rb | 7 +++++++ 4 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 activerecord/test/cases/serialized_sti_test.rb create mode 100644 activerecord/test/models/droid.rb diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb index 2db2722..441a4dd 100644 --- a/activerecord/lib/active_record/attribute_methods.rb +++ b/activerecord/lib/active_record/attribute_methods.rb @@ -65,13 +65,15 @@ module ActiveRecord def define_attribute_methods 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) - define_read_method_for_time_zone_conversion(name) - else - define_read_method(name.to_sym, name, column) + if self.serialized_attributes[name] + define_read_method_for_serialized_attribute(name) + else + unless instance_method_already_implemented?(name) + 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) + end end end diff --git a/activerecord/test/cases/serialized_sti_test.rb b/activerecord/test/cases/serialized_sti_test.rb new file mode 100644 index 0000000..f0c2498 --- /dev/null +++ b/activerecord/test/cases/serialized_sti_test.rb @@ -0,0 +1,15 @@ +require "cases/helper" +require 'models/droid' + +class SerializedStiTest < ActiveRecord::TestCase + def test_sti_subclass_serialized_attribute + c3po = Droid.new(:name => 'C-3PO', :owner => 'Princess Leia', :secret_message => 'What secret message?') + c3po.save + droid1 = Droid.find_by_name('C-3PO') + assert_equal(String, droid1.secret_message.class) + r2d2 = R2D2.new(:name => 'R2D2', :owner => 'Anakin Skywalker', :secret_message => { :to => 'Obi-Wan Kenobi', :from => 'Princess Leia', :message => "Help me Obi-Wan, you're my only hope."}) + r2d2.save + droid2 = Droid.find_by_name('R2D2') + assert_equal(Hash, droid2.secret_message.class) + end +end diff --git a/activerecord/test/models/droid.rb b/activerecord/test/models/droid.rb new file mode 100644 index 0000000..4908c2e --- /dev/null +++ b/activerecord/test/models/droid.rb @@ -0,0 +1,6 @@ +class Droid < ActiveRecord::Base +end + +class R2D2 < Droid + serialize :secret_message +end diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 423929f..7041d5e 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -136,6 +136,13 @@ ActiveRecord::Schema.define do t.integer :access_level, :default => 1 end + create_table :droids, :force => true do |t| + t.string :type + t.string :name + t.string :owner + t.text :secret_message + end + create_table :edges, :force => true do |t| t.column :source_id, :integer, :null => false t.column :sink_id, :integer, :null => false -- 1.5.5.1