Skip to content

Commit 83cc5e5

Browse files
committed
🐛 set columnName and name of the constraint if it's not provided
1 parent 4a31a5a commit 83cc5e5

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

frontend/packages/db-structure/src/parser/schemarb/index.test.ts

+44-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, expect, it } from 'vitest'
1+
import { beforeEach, describe, expect, it, vi } from 'vitest'
22
import type { Table } from '../../schema/index.js'
33
import {
44
aCheckConstraint,
@@ -11,10 +11,21 @@ import {
1111
aUniqueConstraint,
1212
anIndex,
1313
} from '../../schema/index.js'
14+
import * as GenerateRandomIdentifier from './generateRandomIdentifier.js'
1415
import { UnsupportedTokenError, processor } from './index.js'
1516

1617
import { createParserTestCases } from '../__tests__/index.js'
1718

19+
beforeEach(() => {
20+
vi.spyOn(GenerateRandomIdentifier, 'generateRandomIdentifier')
21+
.mockImplementationOnce((length) => `[identifier(${length})_#1]`)
22+
.mockImplementation(() => {
23+
throw Error(
24+
'"generateRandomIdentifier" is called more times than expected. Please add additional "mockImplementationOnce" calls if need',
25+
)
26+
})
27+
})
28+
1829
describe(processor, () => {
1930
const userTable = (override?: Partial<Table>) =>
2031
aSchema({
@@ -302,6 +313,38 @@ describe(processor, () => {
302313
})
303314
})
304315

316+
it('foreign key (without explicit constraint name and column options)', async () => {
317+
const { value } = await processor(/* Ruby */ `
318+
create_table "posts" do |t|
319+
t.bigint "user_id"
320+
end
321+
322+
add_foreign_key "posts", "users"
323+
`)
324+
325+
expect(value.relationships).toEqual({
326+
users_id_to_posts_user_id: aRelationship({
327+
name: 'users_id_to_posts_user_id',
328+
foreignTableName: 'posts',
329+
foreignColumnName: 'user_id',
330+
primaryTableName: 'users',
331+
primaryColumnName: 'id',
332+
}),
333+
})
334+
expect(value.tables['posts']?.constraints).toEqual({
335+
PRIMARY_id: aPrimaryKeyConstraint({
336+
name: 'PRIMARY_id',
337+
columnName: 'id',
338+
}),
339+
'fk_rails_[identifier(10)_#1]': aForeignKeyConstraint({
340+
name: 'fk_rails_[identifier(10)_#1]',
341+
columnName: 'user_id',
342+
targetTableName: 'users',
343+
targetColumnName: 'id',
344+
}),
345+
})
346+
})
347+
305348
describe('foreign key cardinality', () => {
306349
it('foreign key (one-to-many)', async () => {
307350
const keyName = 'fk_posts_user_id'

frontend/packages/db-structure/src/parser/schemarb/parser.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import {
5050
handleOneToOneRelationships,
5151
} from '../utils/index.js'
5252
import { convertColumnType } from './convertColumnType.js'
53+
import { generateRandomIdentifier } from './generateRandomIdentifier.js'
5354
import { loadPrism } from './loadPrism.js'
5455
import { singularize } from './singularize.js'
5556

@@ -422,7 +423,9 @@ function extractForeignKeyOptions(
422423

423424
// ref: https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-add_foreign_key
424425
if (relation.foreignColumnName === '') {
425-
relation.foreignColumnName = `${singularize(relation.primaryTableName)}_id`
426+
const columnName = `${singularize(relation.primaryTableName)}_id`
427+
relation.foreignColumnName = columnName
428+
foreignKeyConstraint.columnName = columnName
426429
}
427430

428431
if (relation.name === '') {
@@ -433,6 +436,10 @@ function extractForeignKeyOptions(
433436
relation.foreignColumnName,
434437
)
435438
}
439+
440+
if (foreignKeyConstraint.name === '') {
441+
foreignKeyConstraint.name = `fk_rails_${generateRandomIdentifier(10)}`
442+
}
436443
}
437444

438445
class SchemaFinder extends Visitor {

0 commit comments

Comments
 (0)