mirror of https://github.com/rails/rails
Always request `primary_key` in `RETURNING` if no other columns requested
Prior 7.1 Rails always included `primary_key` in `RETURNING` clause on record creation. This was changed in 7.1 to include more auto-populated columns if such columns exist. This change lead to situations where no columns were requested in `RETURNING` clause, even the `primary_key`. This change brings back the old behavior of always requesting the `primary_key` in `RETURNING` clause if no other columns are requested.
This commit is contained in:
parent
25b7f64074
commit
c2c861f98a
|
@ -431,8 +431,12 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def _returning_columns_for_insert # :nodoc:
|
||||
@_returning_columns_for_insert ||= columns.filter_map do |c|
|
||||
c.name if connection.return_value_after_insert?(c)
|
||||
@_returning_columns_for_insert ||= begin
|
||||
auto_populated_columns = columns.filter_map do |c|
|
||||
c.name if connection.return_value_after_insert?(c)
|
||||
end
|
||||
|
||||
auto_populated_columns.empty? ? Array(primary_key) : auto_populated_columns
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ require "models/cpk"
|
|||
require "models/chat_message"
|
||||
require "models/default"
|
||||
require "models/post_with_prefetched_pk"
|
||||
require "models/pk_autopopulated_by_a_trigger_record"
|
||||
|
||||
class PersistenceTest < ActiveRecord::TestCase
|
||||
fixtures :topics, :companies, :developers, :accounts, :minimalistics, :authors, :author_addresses,
|
||||
|
@ -1574,6 +1575,13 @@ class PersistenceTest < ActiveRecord::TestCase
|
|||
|
||||
assert_equal("blue", ClothingItem.find_by(id: clothing_item.id).color)
|
||||
end
|
||||
|
||||
def test_model_with_no_auto_populated_fields_still_returns_primary_key_after_insert
|
||||
record = PkAutopopulatedByATriggerRecord.create
|
||||
|
||||
assert_not_nil record.id
|
||||
assert record.id > 0
|
||||
end if current_adapter?(:PostgreSQLAdapter)
|
||||
end
|
||||
|
||||
class QueryConstraintsTest < ActiveRecord::TestCase
|
||||
|
|
|
@ -193,6 +193,12 @@ if ActiveRecord::Base.connection.supports_views?
|
|||
assert_equal "Rails in Action", new_book.name
|
||||
end
|
||||
|
||||
def test_insert_record_populates_primary_key
|
||||
book = PrintedBook.create! name: "Rails in Action", status: 0, format: "paperback"
|
||||
assert_not_nil book.id
|
||||
assert book.id > 0
|
||||
end if current_adapter?(:PostgreSQLAdapter, :SQLite3Adapter) && supports_insert_returning?
|
||||
|
||||
def test_update_record_to_fail_view_conditions
|
||||
book = PrintedBook.first
|
||||
book.format = "ebook"
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class PkAutopopulatedByATriggerRecord < ActiveRecord::Base
|
||||
self.primary_key = :id
|
||||
end
|
|
@ -1483,6 +1483,32 @@ ActiveRecord::Schema.define do
|
|||
end
|
||||
end
|
||||
|
||||
if ActiveRecord::TestCase.current_adapter?(:PostgreSQLAdapter)
|
||||
ActiveRecord::Base.connection.create_table :pk_autopopulated_by_a_trigger_records, force: true, id: false do |t|
|
||||
t.integer :id, null: false
|
||||
end
|
||||
|
||||
ActiveRecord::Base.connection.execute(
|
||||
<<-SQL
|
||||
CREATE OR REPLACE FUNCTION populate_column()
|
||||
RETURNS TRIGGER AS $$
|
||||
DECLARE
|
||||
max_value INTEGER;
|
||||
BEGIN
|
||||
SELECT MAX(id) INTO max_value FROM pk_autopopulated_by_a_trigger_records;
|
||||
NEW.id = COALESCE(max_value, 0) + 1;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER before_insert_trigger
|
||||
BEFORE INSERT ON pk_autopopulated_by_a_trigger_records
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION populate_column();
|
||||
SQL
|
||||
)
|
||||
end
|
||||
|
||||
Course.connection.create_table :courses, force: true do |t|
|
||||
t.column :name, :string, null: false
|
||||
t.column :college_id, :integer, index: true
|
||||
|
|
Loading…
Reference in New Issue