From 1f52f93bb59143fc33fe5f65b41585d46f710b90 Mon Sep 17 00:00:00 2001 From: Zack Hobson Date: Mon, 7 Sep 2009 09:37:15 -0700 Subject: [PATCH] Fix serialized attributes failing with STI. This patch was posted by Les Hill to Rails Lighthouse: https://rails.lighthouseapp.com/projects/8994/tickets/204 --- .../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 3ffc489..82118d9 100644 --- a/activerecord/lib/active_record/attribute_methods.rb +++ b/activerecord/lib/active_record/attribute_methods.rb @@ -69,13 +69,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 87fad0e..aafc481 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -153,6 +153,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.6.4.2