Skip to content

Commit

Permalink
Merge pull request rails#47482 from Shopify/serialization-default
Browse files Browse the repository at this point in the history
Serialized attribute should be able to be defined in abstract classes
  • Loading branch information
byroot committed Feb 23, 2023
2 parents 17c5c0d + c4c0b79 commit b0dd7c7
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 46 deletions.
Expand Up @@ -219,7 +219,7 @@ def serialize(attr_name, class_name_or_coder = nil, coder: nil, type: Object, ya
end

cast_type = cast_type.subtype if Type::Serialized === cast_type
Type::Serialized.new(cast_type, column_serializer, default: columns_hash[attr_name.to_s]&.default)
Type::Serialized.new(cast_type, column_serializer)
end
end

Expand Down
5 changes: 2 additions & 3 deletions activerecord/lib/active_record/type/serialized.rb
Expand Up @@ -9,10 +9,9 @@ class Serialized < DelegateClass(ActiveModel::Type::Value) # :nodoc:

attr_reader :subtype, :coder

def initialize(subtype, coder, default: nil)
def initialize(subtype, coder)
@subtype = subtype
@coder = coder
@default = default
super(subtype)
end

Expand All @@ -26,7 +25,7 @@ def deserialize(value)

def serialize(value)
return if value.nil?
unless default_value?(value) && @default.nil?
unless default_value?(value)
super coder.dump(value)
end
end
Expand Down
51 changes: 9 additions & 42 deletions activerecord/test/cases/serialized_attribute_test.rb
Expand Up @@ -403,51 +403,18 @@ def test_values_cast_from_nil_are_persisted_as_nil
assert_equal [topic, topic2], Topic.where(content: nil).sort_by(&:id)
end

# MySQL doesn't support default values for text columns, so we need to skip this test for MySQL
if !current_adapter?(:Mysql2Adapter)
def test_serialized_attribute_with_default_can_update_to_default
@verbose_was = ActiveRecord::Migration.verbose
ActiveRecord::Migration.verbose = false

ActiveRecord::Schema.define do
create_table :tmp_posts, force: true do |t|
t.text :content, null: false, default: "{}"
end
end
klass = Class.new(ActiveRecord::Base) do
self.table_name = "tmp_posts"
serialize(:content, type: Hash)
end

t = klass.create!(content: { "other_key" => "new_value" })
assert_equal({ "other_key" => "new_value" }, t.content)

t.update!(content: {})
assert_equal({}, t.content)
ensure
ActiveRecord::Migration.verbose = @verbose_was
def test_serialized_attribute_can_be_defined_in_abstract_classes
klass = Class.new(ActiveRecord::Base) do
self.abstract_class = true
self.table_name = nil
serialize(:content, type: Hash)
end

def test_nil_is_always_persisted_as_default
@verbose_was = ActiveRecord::Migration.verbose
ActiveRecord::Migration.verbose = false

ActiveRecord::Schema.define do
create_table :tmp_posts, force: true do |t|
t.text :content, null: false, default: "{}"
end
end
klass = Class.new(ActiveRecord::Base) do
self.table_name = "tmp_posts"
serialize(:content, type: Hash)
end

t = klass.create!(content: { foo: "bar" })
t.update_attribute :content, nil
assert_equal({}, t.content)
ensure
ActiveRecord::Migration.verbose = @verbose_was
subclass = Class.new(klass) do
self.table_name = "posts"
end

subclass.define_attribute_methods
end

def test_nil_is_always_persisted_as_null
Expand Down

0 comments on commit b0dd7c7

Please sign in to comment.