Skip to content

Commit edddc2b

Browse files
authored
Fix mismatched foreign key errors (#1215)
1 parent 8b1c005 commit edddc2b

File tree

3 files changed

+37
-19
lines changed

3 files changed

+37
-19
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,8 @@
99
- [#1153](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1153) Only support Ruby v3.1+
1010
- [#1196](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1196) Use default inspect for database adapter
1111

12+
#### Fixed
13+
14+
- [#1215](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1215) Fix mismatched foreign key errors
15+
1216
Please check [7-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/7-1-stable/CHANGELOG.md) for previous changes.

lib/active_record/connection_adapters/sqlserver_adapter.rb

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -431,36 +431,28 @@ def type_map
431431
TYPE_MAP
432432
end
433433

434-
def translate_exception(e, message:, sql:, binds:)
434+
def translate_exception(exception, message:, sql:, binds:)
435435
case message
436436
when /(SQL Server client is not connected)|(failed to execute statement)/i
437-
ConnectionNotEstablished.new(message)
437+
ConnectionNotEstablished.new(message, connection_pool: @pool)
438438
when /(cannot insert duplicate key .* with unique index) | (violation of (unique|primary) key constraint)/i
439-
RecordNotUnique.new(message, sql: sql, binds: binds)
439+
RecordNotUnique.new(message, sql: sql, binds: binds, connection_pool: @pool)
440440
when /(conflicted with the foreign key constraint) | (The DELETE statement conflicted with the REFERENCE constraint)/i
441-
InvalidForeignKey.new(message, sql: sql, binds: binds)
441+
InvalidForeignKey.new(message, sql: sql, binds: binds, connection_pool: @pool)
442442
when /has been chosen as the deadlock victim/i
443-
DeadlockVictim.new(message, sql: sql, binds: binds)
443+
DeadlockVictim.new(message, sql: sql, binds: binds, connection_pool: @pool)
444444
when /database .* does not exist/i
445-
NoDatabaseError.new(message)
445+
NoDatabaseError.new(message, connection_pool: @pool)
446446
when /data would be truncated/
447-
ValueTooLong.new(message, sql: sql, binds: binds)
447+
ValueTooLong.new(message, sql: sql, binds: binds, connection_pool: @pool)
448448
when /connection timed out/
449-
StatementTimeout.new(message, sql: sql, binds: binds)
449+
StatementTimeout.new(message, sql: sql, binds: binds, connection_pool: @pool)
450450
when /Column '(.*)' is not the same data type as referencing column '(.*)' in foreign key/
451-
pk_id, fk_id = SQLServer::Utils.extract_identifiers($1), SQLServer::Utils.extract_identifiers($2)
452-
MismatchedForeignKey.new(
453-
self,
454-
message: message,
455-
table: fk_id.schema,
456-
foreign_key: fk_id.object,
457-
target_table: pk_id.schema,
458-
primary_key: pk_id.object
459-
)
451+
MismatchedForeignKey.new(message: message, connection_pool: @pool)
460452
when /Cannot insert the value NULL into column.*does not allow nulls/
461-
NotNullViolation.new(message, sql: sql, binds: binds)
453+
NotNullViolation.new(message, sql: sql, binds: binds, connection_pool: @pool)
462454
when /Arithmetic overflow error/
463-
RangeError.new(message, sql: sql, binds: binds)
455+
RangeError.new(message, sql: sql, binds: binds, connection_pool: @pool)
464456
else
465457
super
466458
end

test/cases/adapter_test_sqlserver.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,4 +580,26 @@ def test_doesnt_error_when_a_select_query_is_called_while_preventing_writes
580580
end
581581
end
582582
end
583+
584+
describe "mismatched foreign keys error" do
585+
def setup
586+
@conn = ActiveRecord::Base.lease_connection
587+
end
588+
589+
it 'raises an error when the foreign key is mismatched' do
590+
error = assert_raises(ActiveRecord::MismatchedForeignKey) do
591+
@conn.add_reference :engines, :old_car
592+
@conn.add_foreign_key :engines, :old_cars
593+
end
594+
595+
assert_match(
596+
%r/Column 'old_cars\.id' is not the same data type as referencing column 'engines\.old_car_id' in foreign key '.*'/,
597+
error.message
598+
)
599+
assert_not_nil error.cause
600+
assert_equal @conn.pool, error.connection_pool
601+
ensure
602+
@conn.execute("ALTER TABLE engines DROP COLUMN old_car_id") rescue nil
603+
end
604+
end
583605
end

0 commit comments

Comments
 (0)