diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb index 3c9f61ec0b..26f2124cb7 100644 --- a/activerecord/lib/active_record/attribute_methods.rb +++ b/activerecord/lib/active_record/attribute_methods.rb @@ -387,20 +387,22 @@ module ActiveRecord attribute_names.index_with { |name| @attributes[name] } end - # Filters the primary keys and readonly attributes from the attribute names. + # Filters the primary keys, readonly attributes and virtual columns from the attribute names. def attributes_for_update(attribute_names) attribute_names &= self.class.column_names attribute_names.delete_if do |name| - self.class.readonly_attribute?(name) + self.class.readonly_attribute?(name) || + column_for_attribute(name).virtual? end end - # Filters out the primary keys, from the attribute names, when the primary + # Filters out the virtual columns and also primary keys, from the attribute names, when the primary # key is to be generated (e.g. the id attribute has no value). def attributes_for_create(attribute_names) attribute_names &= self.class.column_names attribute_names.delete_if do |name| - pk_attribute?(name) && id.nil? + (pk_attribute?(name) && id.nil?) || + column_for_attribute(name).virtual? end end diff --git a/activerecord/lib/active_record/connection_adapters/column.rb b/activerecord/lib/active_record/connection_adapters/column.rb index 85521ce9ea..bfff81b91b 100644 --- a/activerecord/lib/active_record/connection_adapters/column.rb +++ b/activerecord/lib/active_record/connection_adapters/column.rb @@ -87,6 +87,10 @@ module ActiveRecord comment.hash end + def virtual? + false + end + private def deduplicated @name = -name diff --git a/activerecord/test/cases/adapters/postgresql/virtual_column_test.rb b/activerecord/test/cases/adapters/postgresql/virtual_column_test.rb index fa6dcc51a6..069e10e74b 100644 --- a/activerecord/test/cases/adapters/postgresql/virtual_column_test.rb +++ b/activerecord/test/cases/adapters/postgresql/virtual_column_test.rb @@ -23,6 +23,16 @@ if ActiveRecord::Base.connection.supports_virtual_columns? VirtualColumn.create(name: "Rails") end + def test_virtual_column_with_full_inserts + partial_inserts_was = VirtualColumn.partial_inserts + VirtualColumn.partial_inserts = false + assert_nothing_raised do + VirtualColumn.create!(name: "Rails") + end + ensure + VirtualColumn.partial_inserts = partial_inserts_was + end + def teardown @connection.drop_table :virtual_columns, if_exists: true VirtualColumn.reset_column_information