From 885f59f6852cce670b48680fa0a1b6a4b0998291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Fri, 21 Dec 2012 14:15:33 -0300 Subject: Serialized attribute can be serialized in an integer column Fix #8575 Conflicts: activerecord/CHANGELOG.md activerecord/lib/active_record/attribute_methods/serialization.rb activerecord/test/cases/serialized_attribute_test.rb activerecord/test/models/person.rb --- activerecord/CHANGELOG.md | 13 ++++++++---- .../attribute_methods/serialization.rb | 8 ++++++++ activerecord/test/cases/base_test.rb | 8 ++++++++ activerecord/test/models/person.rb | 23 +++++++++++++++++++++- activerecord/test/schema/schema.rb | 3 ++- 5 files changed, 49 insertions(+), 6 deletions(-) (limited to 'activerecord') diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index c39d7fe00c..083474eed0 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,14 +1,19 @@ ## Rails 3.2.10 (unreleased) +* Serialized attributes can be serialized in integer columns. + Fix #8575. + + *Rafael Mendonça França* + * Keep index names when using `alter_table` with sqlite3. - Fix #3489 - Backport #8522 + Fix #3489. + Backport #8522. *Yves Senn* * Recognize migrations placed in directories containing numbers and 'rb'. - Fix #8492 - Backport of #8500 + Fix #8492. + Backport of #8500. *Yves Senn* diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb index cf4c35cf84..deb89f3ac1 100644 --- a/activerecord/lib/active_record/attribute_methods/serialization.rb +++ b/activerecord/lib/active_record/attribute_methods/serialization.rb @@ -90,6 +90,14 @@ module ActiveRecord end end + def _field_changed?(attr, old, value) + if self.class.serialized_attributes.include?(attr) + old != value + else + super + end + end + def read_attribute_before_type_cast(attr_name) if serialized_attributes.include?(attr_name) super.unserialized_value diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 3b2aae0360..b849eead26 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1457,6 +1457,14 @@ class BasicsTest < ActiveRecord::TestCase ActiveRecord::Base.time_zone_aware_attributes = false end + def test_serialize_attribute_can_be_serialized_in_an_integer_column + insures = ['life'] + person = SerializedPerson.new(:first_name => 'David', :insures => insures) + assert person.save + person = person.reload + assert_equal(insures, person.insures) + end + def test_quote author_name = "\\ \001 ' \n \\n \"" topic = Topic.create('author_name' => author_name) diff --git a/activerecord/test/models/person.rb b/activerecord/test/models/person.rb index 5991aed55b..07c529d685 100644 --- a/activerecord/test/models/person.rb +++ b/activerecord/test/models/person.rb @@ -89,6 +89,27 @@ class TightDescendant < TightPerson; end class RichPerson < ActiveRecord::Base self.table_name = 'people' - + has_and_belongs_to_many :treasures, :join_table => 'peoples_treasures' end + +class Insure + INSURES = %W{life annuality} + + def self.load mask + INSURES.select do |insure| + (1 << INSURES.index(insure)) & mask.to_i > 0 + end + end + + def self.dump insures + numbers = insures.map { |insure| INSURES.index(insure) } + numbers.inject(0) { |sum, n| sum + (1 << n) } + end +end + +class SerializedPerson < ActiveRecord::Base + self.table_name = 'people' + + serialize :insures, Insure +end diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index fa4ac7c89b..1a993fef11 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -479,9 +479,10 @@ ActiveRecord::Schema.define do t.integer :followers_count, :default => 0 t.references :best_friend t.references :best_friend_of + t.integer :insures, :null => false, :default => 0 t.timestamps end - + create_table :peoples_treasures, :id => false, :force => true do |t| t.column :rich_person_id, :integer t.column :treasure_id, :integer -- cgit v1.2.3