From 95915e2711d160dfe98708edc4280db685e0847b Mon Sep 17 00:00:00 2001 From: Nicolas Bachschmidt Date: Thu, 24 Oct 2024 15:11:09 +0200 Subject: [PATCH 1/2] Deserialize auto populated columns on Active Record object creation Values returned from the databases need to be deserialized as they may use a different format, such as PostgreSQL bytea "hex" format. Fix #53435 --- activerecord/lib/active_record/persistence.rb | 2 +- activerecord/test/cases/persistence_test.rb | 2 ++ activerecord/test/schema/postgresql_specific_schema.rb | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index 935f0353658b7..5fdb9b275b142 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -930,7 +930,7 @@ def _create_record(attribute_names = self.attribute_names) ) returning_columns.zip(returning_values).each do |column, value| - _write_attribute(column, value) if !_read_attribute(column) + @attributes.write_from_database(column, value) if !_read_attribute(column) end if returning_values end diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb index 62ac4b54021ea..29cd0b6e7db90 100644 --- a/activerecord/test/cases/persistence_test.rb +++ b/activerecord/test/cases/persistence_test.rb @@ -63,6 +63,8 @@ def test_fills_auto_populated_columns_on_creation assert_not_nil record.modified_time_without_precision assert_not_nil record.modified_time_function + assert_equal "A", record.binary_default_function + if supports_identity_columns? klass = Class.new(ActiveRecord::Base) do self.table_name = "postgresql_identity_table" diff --git a/activerecord/test/schema/postgresql_specific_schema.rb b/activerecord/test/schema/postgresql_specific_schema.rb index 62ba429aeb9da..129dd2a0b8a11 100644 --- a/activerecord/test/schema/postgresql_specific_schema.rb +++ b/activerecord/test/schema/postgresql_specific_schema.rb @@ -41,6 +41,7 @@ t.string :char2, limit: 50, default: "a varchar field" t.text :char3, default: "a text field" t.bigint :bigint_default, default: -> { "0::bigint" } + t.binary :binary_default_function, default: -> { "convert_to('A', 'UTF8')" } t.text :multiline_default, default: "--- [] " From fdfe0fbafe523f7ce6fdd1e87019076be6a486f4 Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Wed, 30 Oct 2024 15:29:18 +0900 Subject: [PATCH 2/2] Use `_write_attribute` back to work changes tracking --- activerecord/lib/active_record/persistence.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index 5fdb9b275b142..1d03c0e921002 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -930,7 +930,7 @@ def _create_record(attribute_names = self.attribute_names) ) returning_columns.zip(returning_values).each do |column, value| - @attributes.write_from_database(column, value) if !_read_attribute(column) + _write_attribute(column, type_for_attribute(column).deserialize(value)) if !_read_attribute(column) end if returning_values end