Skip to content

Commit 96a7d11

Browse files
authored
Merge pull request #10 from SoftwareBrothers/fix-relations
[fix] Fix relationships in typeorm adapter
2 parents fb43c32 + 08de41a commit 96a7d11

File tree

10 files changed

+41
-41
lines changed

10 files changed

+41
-41
lines changed

ormconfig.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module.exports = {
22
type: 'postgres',
33
host: process.env.POSTGRES_HOST || 'localhost',
44
port: +(process.env.POSTGRES_PORT || 5432),
5-
username: process.env.POSTGRES_USER || 'postgres',
5+
username: process.env.POSTGRES_USER || '',
66
password: process.env.POSTGRES_PASSWORD || '',
77
database: process.env.POSTGRES_DATABASE || 'database_test',
88
entities: ['spec/entities/**/*.ts'],

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@admin-bro/typeorm",
3-
"version": "1.4.0-beta.2",
3+
"version": "1.4.0",
44
"description": "TypeORM adapter for AdminBro",
55
"keywords": [
66
"typeorm",

spec/Property.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ describe('Property', () => {
2323

2424
describe('#name', () => {
2525
it('returns a name of the property', () => {
26-
const column = columns.find((c) => c.propertyName === 'id') as ColumnMetadata
26+
const column = columns.find((c) => c.propertyName === 'carId') as ColumnMetadata
2727

28-
expect(new Property(column).name()).to.equal('id')
28+
expect(new Property(column).name()).to.equal('carId')
2929
})
3030
})
3131

@@ -37,15 +37,15 @@ describe('Property', () => {
3737
})
3838

3939
it('returns the path of the property', () => {
40-
const column = columns.find((c) => c.propertyName === 'carDealer') as ColumnMetadata
40+
const column = columns.find((c) => c.propertyName === 'carDealerId') as ColumnMetadata
4141

4242
expect(new Property(column).path()).to.equal('carDealerId')
4343
})
4444
})
4545

4646
describe('#isId', () => {
4747
it('returns true for primary key', () => {
48-
const column = columns.find((c) => c.propertyName === 'id') as ColumnMetadata
48+
const column = columns.find((c) => c.propertyName === 'carId') as ColumnMetadata
4949

5050
expect(new Property(column).isId()).to.equal(true)
5151
})
@@ -59,7 +59,7 @@ describe('Property', () => {
5959

6060
describe('#isEditable', () => {
6161
it('returns false for id field', async () => {
62-
const column = columns.find((c) => c.propertyName === 'id') as ColumnMetadata
62+
const column = columns.find((c) => c.propertyName === 'carId') as ColumnMetadata
6363

6464
expect(new Property(column).isEditable()).to.equal(false)
6565
})
@@ -81,7 +81,7 @@ describe('Property', () => {
8181

8282
describe('#reference', () => {
8383
it('returns the name of the referenced resource if any', () => {
84-
const column = columns.find((c) => c.propertyName === 'carDealer') as ColumnMetadata
84+
const column = columns.find((c) => c.propertyName === 'carDealerId') as ColumnMetadata
8585

8686
expect(new Property(column).reference()).to.equal('CarDealer')
8787
})

spec/Resource.spec.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,19 +68,19 @@ describe('Resource', () => {
6868

6969
describe('#properties', () => {
7070
it('returns all the properties', () => {
71-
expect(resource.properties()).to.have.lengthOf(12)
71+
expect(resource.properties()).to.have.lengthOf(13)
7272
})
7373

7474
it('returns all properties with the correct position', () => {
7575
expect(resource.properties().map((property) => property.position())).to.deep.equal([
76-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
76+
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
7777
])
7878
})
7979
})
8080

8181
describe('#property', () => {
8282
it('returns selected property', () => {
83-
const property = resource.property('id')
83+
const property = resource.property('carId')
8484

8585
expect(property).to.be.an.instanceOf(BaseProperty)
8686
})
@@ -111,26 +111,26 @@ describe('Resource', () => {
111111
const params = await resource.create(data)
112112

113113
// eslint-disable-next-line no-unused-expressions
114-
expect(params.id).not.to.be.undefined
114+
expect(params.carId).not.to.be.undefined
115115
})
116116

117117
it('stores Column with defined name property', async () => {
118118
const params = await resource.create(data)
119-
const storedRecord = await Car.findOne(params.id) as Car
119+
const storedRecord = await Car.findOne(params.carId) as Car
120120

121121
expect(storedRecord.streetNumber).to.equal(data.streetNumber)
122122
})
123123

124124
it('stores number Column with property as string', async () => {
125125
const params = await resource.create(data)
126-
const storedRecord = await Car.findOne(params.id) as Car
126+
const storedRecord = await Car.findOne(params.carId) as Car
127127

128128
expect(storedRecord.stringAge).to.equal(4)
129129
})
130130

131131
it('stores mixed type properties', async () => {
132132
const params = await resource.create(data)
133-
const storedRecord = await Car.findOne(params.id) as Car
133+
const storedRecord = await Car.findOne(params.carId) as Car
134134

135135
expect(storedRecord.meta).to.deep.equal({
136136
title: data['meta.title'],
@@ -186,7 +186,7 @@ describe('Resource', () => {
186186
age: 4,
187187
stringAge: '4',
188188
})
189-
record = await resource.findOne(params.id)
189+
record = await resource.findOne(params.carId)
190190
})
191191

192192
it('updates record name', async () => {
@@ -233,10 +233,10 @@ describe('Resource', () => {
233233
it('creates new resource with uuid', async () => {
234234
carParams = await resource.create({
235235
...data,
236-
carBuyerId: carBuyer.id,
236+
carBuyerId: carBuyer.carBuyerId,
237237
})
238238

239-
expect(carParams.carBuyerId).to.equal(carBuyer.id)
239+
expect(carParams.carBuyerId).to.equal(carBuyer.carBuyerId)
240240
})
241241
})
242242

@@ -251,12 +251,12 @@ describe('Resource', () => {
251251
})
252252

253253
afterEach(async () => {
254-
await Car.delete(carParams.id)
254+
await Car.delete(carParams.carId)
255255
await CarDealer.delete(carDealer)
256256
})
257257

258258
it('deletes the resource', async () => {
259-
await resource.delete(carParams.id)
259+
await resource.delete(carParams.carId)
260260
expect(await resource.count({} as Filter)).to.eq(0)
261261
})
262262

spec/entities/Car.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {
22
Entity, Column, PrimaryGeneratedColumn, BaseEntity, ManyToOne,
3-
RelationId, UpdateDateColumn, CreateDateColumn,
3+
JoinColumn, UpdateDateColumn, CreateDateColumn, RelationId,
44
} from 'typeorm'
55
import { IsDefined, Min, Max } from 'class-validator'
66
import { CarDealer } from './CarDealer'
@@ -15,7 +15,7 @@ export enum CarType {
1515
@Entity()
1616
export class Car extends BaseEntity {
1717
@PrimaryGeneratedColumn()
18-
public id: number;
18+
public carId: number;
1919

2020
@Column()
2121
@IsDefined()
@@ -51,16 +51,23 @@ export class Car extends BaseEntity {
5151
public meta;
5252

5353
@ManyToOne(() => CarDealer, (carDealer) => carDealer.cars)
54+
@JoinColumn({
55+
name: 'car_dealer_id',
56+
})
5457
public carDealer: CarDealer;
5558

56-
@RelationId((car: Car) => car.carDealer)
59+
@Column({ name: 'car_dealer_id', type: 'integer', nullable: true })
5760
public carDealerId: number;
5861

5962
@ManyToOne(() => CarBuyer, (carBuyer) => carBuyer.cars)
63+
// @JoinColumn({
64+
// name: 'car_buyer_id',
65+
// })
6066
public carBuyer: CarBuyer;
6167

68+
@Column({ name: 'car_buyer_id', type: 'uuid', nullable: true })
6269
@RelationId((car: Car) => car.carBuyer)
63-
public carBuyerId: number;
70+
public carBuyerId: string;
6471

6572
@CreateDateColumn({ name: 'created_at' })
6673
public createdAt: Date;

spec/entities/CarBuyer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Car } from './Car'
55
@Entity()
66
export class CarBuyer extends BaseEntity {
77
@PrimaryGeneratedColumn('uuid')
8-
public id: string;
8+
public carBuyerId: string;
99

1010
@Column()
1111
@IsDefined()

src/Property.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ export class Property extends BaseProperty {
88
private columnPosition: number;
99

1010
constructor(column: ColumnMetadata, columnPosition = 0) {
11-
// for reference fields take database name (with ...Id)
12-
const path = column.referencedColumn ? column.databaseName : column.propertyPath
11+
const path = column.propertyPath
1312
super({ path })
1413
this.column = column
1514
this.columnPosition = columnPosition

src/Resource.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,16 +152,15 @@ export class Resource extends BaseResource {
152152
if (param === null) {
153153
preparedParams[property.column.propertyName] = null
154154
} else {
155-
// references cannot be stored as an IDs in typeorm, so in order to mimic this) and
156-
// not fetching reference resource) change this:
157-
// { postId: "1" }
158-
// to that:
159-
// { post: { id: 1 } }
155+
const [ref, foreignKey] = property.column.propertyPath.split('.')
160156
const id = (property.column.type === Number) ? Number(param) : param
161-
preparedParams[property.column.propertyName] = { id }
157+
preparedParams[ref] = foreignKey ? {
158+
[foreignKey]: id,
159+
} : id
162160
}
163161
}
164162
})
163+
165164
return preparedParams
166165
}
167166

src/utils/convertFilter.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,8 @@ export function convertFilter(filter?: Filter): FindConditions<BaseEntity> {
2626
} else if ((one.property as Property).column.type === 'enum') {
2727
where[n] = one.value
2828
} else if ((one.property as Property).type() === 'reference') {
29-
// when comes to reference TypeORM cannot filter by referenceId: YOUR_FILTER_VALUE
30-
// I don't know why. But it filters by an object: reference: {id: YOUR_FILTER_VALUE}
31-
// propertyPath holds `reference.id` that is why we split it by `.`
32-
const [column, key] = (one.property as Property).column.propertyPath.split('.')
33-
where[column] = {
34-
[key]: one.value,
35-
}
29+
const [column] = (one.property as Property).column.propertyPath.split('.')
30+
where[column] = one.value
3631
} else {
3732
where[n] = Like(`%${one.value}%`)
3833
}

src/utils/data-types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const DATE = [
4343
// WithPrecisionColumnType:
4444
'datetime', 'datetime2', 'datetimeoffset', 'time', 'time with time zone',
4545
'time without time zone', 'timestamp', 'timestamp without time zone',
46-
'timestamp with time zone', 'timestamp with local time zone',
46+
'timestamp with time zone', 'timestamp with local time zone', 'timestamptz',
4747

4848
// SimpleColumnType:
4949
'timestamp with local time zone', 'smalldatetime', 'date',

0 commit comments

Comments
 (0)