From 3bc3751f09de61c7496483b310610f08a203b605 Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Mon, 7 Jul 2025 14:50:44 +0100 Subject: [PATCH 1/2] Foreign keys are expected in reverse order --- .../sqlserver/schema_statements.rb | 2 +- test/cases/coerced_tests.rb | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/active_record/connection_adapters/sqlserver/schema_statements.rb b/lib/active_record/connection_adapters/sqlserver/schema_statements.rb index c1fd12c61..996f81e91 100644 --- a/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +++ b/lib/active_record/connection_adapters/sqlserver/schema_statements.rb @@ -269,7 +269,7 @@ def foreign_keys(table_name) identifier = SQLServer::Utils.extract_identifiers(table_name) fk_info = execute_procedure :sp_fkeys, nil, identifier.schema, nil, identifier.object, identifier.schema - grouped_fk = fk_info.group_by { |row| row["FK_NAME"] }.values.each { |group| group.sort_by! { |row| row["KEY_SEQ"] } } + grouped_fk = fk_info.group_by { |row| row["FK_NAME"] }.values.each { |group| group.sort_by! { |row| row["KEY_SEQ"] } }.reverse grouped_fk.map do |group| row = group.first options = { diff --git a/test/cases/coerced_tests.rb b/test/cases/coerced_tests.rb index c8c148b3a..23e471c3f 100644 --- a/test/cases/coerced_tests.rb +++ b/test/cases/coerced_tests.rb @@ -838,6 +838,34 @@ def migrate(x) nil end end + + # Foreign key count is the same as PostgreSQL/SQLite. + coerce_tests! :test_remove_foreign_key_on_8_0 + def test_remove_foreign_key_on_8_0_coerced + connection.create_table(:sub_testings) do |t| + t.references :testing, foreign_key: true, type: :bigint + t.references :experiment, foreign_key: { to_table: :testings }, type: :bigint + end + + migration = Class.new(ActiveRecord::Migration[8.0]) do + def up + change_table(:sub_testings) do |t| + t.remove_foreign_key :testings + t.remove_foreign_key :testings, column: :experiment_id + end + end + end + + assert_raise(StandardError, match: /Table 'sub_testings' has no foreign key for testings$/) { + ActiveRecord::Migrator.new(:up, [migration], @schema_migration, @internal_metadata).migrate + } + + foreign_keys = @connection.foreign_keys("sub_testings") + assert_equal 2, foreign_keys.size + ensure + connection.drop_table(:sub_testings, if_exists: true) + ActiveRecord::Base.clear_cache! + end end end end From f6a830d9a3cedf699ed23f05a3877bca470c3ad9 Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Mon, 7 Jul 2025 15:25:40 +0100 Subject: [PATCH 2/2] Update coerced_tests.rb --- test/cases/coerced_tests.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cases/coerced_tests.rb b/test/cases/coerced_tests.rb index 23e471c3f..cf9e26db4 100644 --- a/test/cases/coerced_tests.rb +++ b/test/cases/coerced_tests.rb @@ -844,7 +844,7 @@ def migrate(x) def test_remove_foreign_key_on_8_0_coerced connection.create_table(:sub_testings) do |t| t.references :testing, foreign_key: true, type: :bigint - t.references :experiment, foreign_key: { to_table: :testings }, type: :bigint + t.references :experiment, foreign_key: {to_table: :testings}, type: :bigint end migration = Class.new(ActiveRecord::Migration[8.0]) do