diff --git a/activerecord/lib/active_record/attribute.rb b/activerecord/lib/active_record/attribute.rb index 8cc19045757f6e0acbba984df4802a33fa875445..88536eaac0d920979b631cdd37bfd59b6fe12623 100644 --- a/activerecord/lib/active_record/attribute.rb +++ b/activerecord/lib/active_record/attribute.rb @@ -9,6 +9,10 @@ def from_user(name, value, type) FromUser.new(name, value, type) end + def with_cast_value(name, value, type) + WithCastValue.new(name, value, type) + end + def null(name) Null.new(name) end @@ -58,6 +62,10 @@ def with_value_from_database(value) self.class.from_database(name, value, type) end + def with_cast_value(value) + self.class.with_cast_value(name, value, type) + end + def type_cast(*) raise NotImplementedError end @@ -93,6 +101,16 @@ def type_cast(value) end end + class WithCastValue < Attribute # :nodoc: + def type_cast(value) + value + end + + def changed_in_place_from?(old_value) + false + end + end + class Null < Attribute # :nodoc: def initialize(name) super(name, nil, Type::Value.new) diff --git a/activerecord/lib/active_record/attribute_methods/write.rb b/activerecord/lib/active_record/attribute_methods/write.rb index b3c8209a74b9e159229acbfe956ac55d55dce13b..16804f86bfe7cefaa112bd70530f32cbb65d1aab 100644 --- a/activerecord/lib/active_record/attribute_methods/write.rb +++ b/activerecord/lib/active_record/attribute_methods/write.rb @@ -73,7 +73,7 @@ def write_attribute_with_type_cast(attr_name, value, should_type_cast) if should_type_cast @attributes.write_from_user(attr_name, value) else - @attributes.write_from_database(attr_name, value) + @attributes.write_cast_value(attr_name, value) end value diff --git a/activerecord/lib/active_record/attribute_set.rb b/activerecord/lib/active_record/attribute_set.rb index 6b1d7ea79e9635dc961ebfe50257ed531c85e11b..66fcaf69458b86cd625bceb0d3b865b8d74fb885 100644 --- a/activerecord/lib/active_record/attribute_set.rb +++ b/activerecord/lib/active_record/attribute_set.rb @@ -39,6 +39,10 @@ def write_from_user(name, value) attributes[name] = self[name].with_value_from_user(value) end + def write_cast_value(name, value) + attributes[name] = self[name].with_cast_value(value) + end + def freeze @attributes.freeze super diff --git a/activerecord/test/cases/serialized_attribute_test.rb b/activerecord/test/cases/serialized_attribute_test.rb index 66f345d80595925b2beed5de9275e6ff84469c19..56a0e92e1dc5ab3739ad2eb4dc22151914fcd833 100644 --- a/activerecord/test/cases/serialized_attribute_test.rb +++ b/activerecord/test/cases/serialized_attribute_test.rb @@ -243,8 +243,9 @@ def test_serialized_column_should_unserialize_after_update_column t = Topic.create(content: "first") assert_equal("first", t.content) - t.update_column(:content, Topic.type_for_attribute('content').type_cast_for_database("second")) - assert_equal("second", t.content) + t.update_column(:content, ["second"]) + assert_equal(["second"], t.content) + assert_equal(["second"], t.reload.content) end def test_serialized_column_should_unserialize_after_update_attribute @@ -253,5 +254,6 @@ def test_serialized_column_should_unserialize_after_update_attribute t.update_attribute(:content, "second") assert_equal("second", t.content) + assert_equal("second", t.reload.content) end end