diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb index 40b58606eb1fd..d393f1d41fbb7 100644 --- a/activerecord/lib/active_record/attribute_methods/dirty.rb +++ b/activerecord/lib/active_record/attribute_methods/dirty.rb @@ -251,7 +251,7 @@ def attribute_names_for_partial_inserts changed_attribute_names_to_save else attribute_names.reject do |attr_name| - if column_for_attribute(attr_name).default_function + if column_for_attribute(attr_name).auto_populated? !attribute_changed?(attr_name) end end diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb index f7c4a9e423fac..658309fe06a4e 100644 --- a/activerecord/test/cases/dirty_test.rb +++ b/activerecord/test/cases/dirty_test.rb @@ -972,6 +972,20 @@ def check_around end end + if current_adapter?(:PostgreSQLAdapter) && supports_identity_columns? + test "partial insert off with changed composite identity primary key attribute" do + klass = Class.new(ActiveRecord::Base) do + self.table_name = "cpk_postgresql_identity_table" + end + + with_partial_writes(klass, false) do + record = klass.create!(another_id: 10) + assert_equal 10, record.another_id + assert_not_nil record.id + end + end + end + test "attribute_changed? properly type casts enum values" do parrot = LiveParrot.create!(name: "Scipio", breed: :african) diff --git a/activerecord/test/schema/postgresql_specific_schema.rb b/activerecord/test/schema/postgresql_specific_schema.rb index 13d64b061d492..e8be384b1830f 100644 --- a/activerecord/test/schema/postgresql_specific_schema.rb +++ b/activerecord/test/schema/postgresql_specific_schema.rb @@ -53,6 +53,15 @@ id INT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY ) SQL + + drop_table "cpk_postgresql_identity_table", if_exists: true + execute <<~SQL + create table cpk_postgresql_identity_table ( + another_id INT NOT NULL, + id INT NOT NULL GENERATED BY DEFAULT AS IDENTITY, + CONSTRAINT cpk_postgresql_identity_table_pkey PRIMARY KEY (another_id, id) + ) + SQL end create_table :postgresql_times, force: true do |t|