Skip to content

Commit

Permalink
refactor: move relationships persistance hydration to relation class
Browse files Browse the repository at this point in the history
This will allow others parts of the codebase (not just the relationship persistance client)
to hydrate models with correct foreign keys
  • Loading branch information
thetutlage committed May 24, 2020
1 parent 0f14b0f commit e443b20
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 79 deletions.
25 changes: 25 additions & 0 deletions adonis-typings/relations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,11 @@ declare module '@ioc:Adonis/Lucid/Relations' {
parent: InstanceType<ParentModel>,
client: QueryClientContract,
): HasOneClientContract<this, RelatedModel>

/**
* Hydrates related model attributes for persistance
*/
hydrateForPersistance (parent: LucidRow, values: ModelObject | LucidRow): void
}

/**
Expand Down Expand Up @@ -374,6 +379,11 @@ declare module '@ioc:Adonis/Lucid/Relations' {
parent: InstanceType<ParentModel>,
client: QueryClientContract,
): HasManyClientContract<this, RelatedModel>

/**
* Hydrates related model attributes for persistance
*/
hydrateForPersistance (parent: LucidRow, values: ModelObject | LucidRow): void
}

/**
Expand Down Expand Up @@ -420,6 +430,11 @@ declare module '@ioc:Adonis/Lucid/Relations' {
parent: InstanceType<ParentModel>,
client: QueryClientContract,
): BelongsToClientContract<this, RelatedModel>

/**
* Hydrates parent model attributes for persistance
*/
hydrateForPersistance (parent: LucidRow, values: ModelObject | LucidRow): void
}

/**
Expand Down Expand Up @@ -471,6 +486,16 @@ declare module '@ioc:Adonis/Lucid/Relations' {
parent: OneOrMany<InstanceType<ParentModel>>,
client: QueryClientContract,
): ManyToManyQueryBuilderContract<RelatedModel, InstanceType<RelatedModel>>

/**
* Returns key-value pair for the pivot table in relation to the parent model
*/
getPivotPair (parent: LucidRow): [string, number | string]

/**
* Returns key-value pair for the pivot table in relation to the related model
*/
getPivotRelatedPair (related: LucidRow): [string, number | string]
}

/**
Expand Down
11 changes: 2 additions & 9 deletions src/Orm/Relations/BelongsTo/QueryClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { BelongsToClientContract } from '@ioc:Adonis/Lucid/Relations'

import { BelongsTo } from './index'
import { BelongsToQueryBuilder } from './QueryBuilder'
import { getValue, managedTransaction } from '../../../utils'
import { managedTransaction } from '../../../utils'

/**
* Query client for executing queries in scope to the belongsTo relationship.
Expand All @@ -27,13 +27,6 @@ export class BelongsToQueryClient implements BelongsToClientContract<BelongsTo,
) {
}

/**
* Returns value for the foreign key from the related model
*/
private getForeignKeyValue (related: LucidRow, action: string) {
return getValue(related, this.relation.localKey, this.relation, action)
}

/**
* Generate a query builder instance
*/
Expand Down Expand Up @@ -88,7 +81,7 @@ export class BelongsToQueryClient implements BelongsToClientContract<BelongsTo,
related.$trx = trx
await related.save()

this.parent[this.relation.foreignKey] = this.getForeignKeyValue(related, 'associate')
this.relation.hydrateForPersistance(this.parent, related)
this.parent.$trx = trx
await this.parent.save()
})
Expand Down
12 changes: 10 additions & 2 deletions src/Orm/Relations/BelongsTo/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
* file that was distributed with this source code.
*/

import { LucidModel, LucidRow } from '@ioc:Adonis/Lucid/Model'
import { QueryClientContract } from '@ioc:Adonis/Lucid/Database'
import { OneOrMany } from '@ioc:Adonis/Lucid/DatabaseQueryBuilder'
import { LucidModel, LucidRow, ModelObject } from '@ioc:Adonis/Lucid/Model'

import {
RelationOptions,
BelongsToRelationContract,
Expand All @@ -18,7 +19,7 @@ import {

import { KeysExtractor } from '../KeysExtractor'
import { BelongsToQueryClient } from './QueryClient'
import { ensureRelationIsBooted } from '../../../utils'
import { ensureRelationIsBooted, getValue } from '../../../utils'

/**
* Manages loading and persisting belongs to relationship
Expand Down Expand Up @@ -183,4 +184,11 @@ export class BelongsTo implements BelongsToRelationContract<LucidModel, LucidMod
ensureRelationIsBooted(this)
return BelongsToQueryClient.eagerQuery(client, this, parent)
}

/**
* Hydrates values object for persistance.
*/
public hydrateForPersistance (parent: LucidRow, related: ModelObject | LucidRow) {
parent[this.foreignKey] = getValue(related, this.localKey, this, 'associate')
}
}
49 changes: 25 additions & 24 deletions src/Orm/Relations/HasMany/QueryClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { LucidRow, LucidModel, ModelObject } from '@ioc:Adonis/Lucid/Model'

import { HasMany } from './index'
import { HasManyQueryBuilder } from './QueryBuilder'
import { getValue, managedTransaction } from '../../../utils'
import { managedTransaction } from '../../../utils'

/**
* Query client for executing queries in scope to the defined
Expand Down Expand Up @@ -48,13 +48,6 @@ export class HasManyQueryClient implements HasManyClientContract<HasMany, LucidM
return query
}

/**
* Returns value for the foreign key
*/
private getForeignKeyValue (parent: LucidRow, action: string) {
return getValue(parent, this.relation.localKey, this.relation, action)
}

/**
* Returns instance of query builder
*/
Expand All @@ -70,7 +63,7 @@ export class HasManyQueryClient implements HasManyClientContract<HasMany, LucidM
this.parent.$trx = trx
await this.parent.save()

related[this.relation.foreignKey] = this.getForeignKeyValue(this.parent, 'save')
this.relation.hydrateForPersistance(this.parent, related)
related.$trx = trx
await related.save()
})
Expand All @@ -86,9 +79,8 @@ export class HasManyQueryClient implements HasManyClientContract<HasMany, LucidM
this.parent.$trx = trx
await parent.save()

const foreignKeyValue = this.getForeignKeyValue(parent, 'saveMany')
for (let row of related) {
row[this.relation.foreignKey] = foreignKeyValue
this.relation.hydrateForPersistance(this.parent, row)
row.$trx = trx
await row.save()
}
Expand All @@ -103,9 +95,9 @@ export class HasManyQueryClient implements HasManyClientContract<HasMany, LucidM
this.parent.$trx = trx
await this.parent.save()

return this.relation.relatedModel().create(Object.assign({
[this.relation.foreignKey]: this.getForeignKeyValue(this.parent, 'create'),
}, values), { client: trx })
const valuesToPersist = Object.assign({}, values)
this.relation.hydrateForPersistance(this.parent, valuesToPersist)
return this.relation.relatedModel().create(valuesToPersist, { client: trx })
})
}

Expand All @@ -119,10 +111,13 @@ export class HasManyQueryClient implements HasManyClientContract<HasMany, LucidM
this.parent.$trx = trx
await parent.save()

const foreignKeyValue = this.getForeignKeyValue(parent, 'createMany')
return this.relation.relatedModel().createMany(values.map((value) => {
return Object.assign({ [this.relation.foreignKey]: foreignKeyValue }, value)
}), { client: trx })
const valuesToPersist = values.map((value) => {
const valueToPersist = Object.assign({}, value)
this.relation.hydrateForPersistance(this.parent, valueToPersist)
return valueToPersist
})

return this.relation.relatedModel().createMany(valuesToPersist, { client: trx })
})
}

Expand All @@ -134,9 +129,12 @@ export class HasManyQueryClient implements HasManyClientContract<HasMany, LucidM
this.parent.$trx = trx
await this.parent.save()

return this.relation.relatedModel().firstOrCreate(Object.assign({
[this.relation.foreignKey]: this.getForeignKeyValue(this.parent, 'firstOrCreate'),
}, search), savePayload, { client: trx })
const valuesToPersist = Object.assign({}, search)
this.relation.hydrateForPersistance(this.parent, valuesToPersist)

return this.relation
.relatedModel()
.firstOrCreate(valuesToPersist, savePayload, { client: trx })
})
}

Expand All @@ -151,9 +149,12 @@ export class HasManyQueryClient implements HasManyClientContract<HasMany, LucidM
this.parent.$trx = trx
await this.parent.save()

return this.relation.relatedModel().updateOrCreate(Object.assign({
[this.relation.foreignKey]: this.getForeignKeyValue(this.parent, 'updateOrCreate'),
}, search), updatePayload, { client: trx })
const valuesToPersist = Object.assign({}, search)
this.relation.hydrateForPersistance(this.parent, valuesToPersist)

return this.relation
.relatedModel()
.updateOrCreate(valuesToPersist, updatePayload, { client: trx })
})
}
}
12 changes: 10 additions & 2 deletions src/Orm/Relations/HasMany/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
* file that was distributed with this source code.
*/

import { LucidModel, LucidRow } from '@ioc:Adonis/Lucid/Model'
import { QueryClientContract } from '@ioc:Adonis/Lucid/Database'
import { OneOrMany } from '@ioc:Adonis/Lucid/DatabaseQueryBuilder'
import { LucidModel, LucidRow, ModelObject } from '@ioc:Adonis/Lucid/Model'

import {
RelationOptions,
HasManyRelationContract,
Expand All @@ -18,7 +19,7 @@ import {

import { KeysExtractor } from '../KeysExtractor'
import { HasManyQueryClient } from './QueryClient'
import { ensureRelationIsBooted } from '../../../utils'
import { ensureRelationIsBooted, getValue } from '../../../utils'

/**
* Manages persisting and fetching relationships
Expand Down Expand Up @@ -188,4 +189,11 @@ export class HasMany implements HasManyRelationContract<LucidModel, LucidModel>
ensureRelationIsBooted(this)
return HasManyQueryClient.eagerQuery(client, this, parent)
}

/**
* Hydrates values object for persistance.
*/
public hydrateForPersistance (parent: LucidRow, values: ModelObject | LucidRow) {
values[this.foreignKey] = getValue(parent, this.localKey, this, 'persist')
}
}
35 changes: 17 additions & 18 deletions src/Orm/Relations/HasOne/QueryClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { ModelObject, LucidModel, LucidRow } from '@ioc:Adonis/Lucid/Model'

import { HasOne } from './index'
import { HasOneQueryBuilder } from './QueryBuilder'
import { getValue, managedTransaction } from '../../../utils'
import { managedTransaction } from '../../../utils'

/**
* Query client for executing queries in scope to the defined
Expand Down Expand Up @@ -49,13 +49,6 @@ export class HasOneQueryClient implements HasOneClientContract<HasOne, LucidMode
return query
}

/**
* Returns value for the foreign key
*/
private getForeignKeyValue (parent: LucidRow, action: string) {
return getValue(parent, this.relation.localKey, this.relation, action)
}

/**
* Returns instance of query builder
*/
Expand All @@ -71,7 +64,7 @@ export class HasOneQueryClient implements HasOneClientContract<HasOne, LucidMode
this.parent.$trx = trx
await this.parent.save()

related[this.relation.foreignKey] = this.getForeignKeyValue(this.parent, 'save')
this.relation.hydrateForPersistance(this.parent, related)
related.$trx = trx
await related.save()
})
Expand All @@ -87,9 +80,9 @@ export class HasOneQueryClient implements HasOneClientContract<HasOne, LucidMode
this.parent.$trx = trx
await parent.save()

return this.relation.relatedModel().create(Object.assign({
[this.relation.foreignKey]: this.getForeignKeyValue(parent, 'create'),
}, values), { client: trx })
const valuesToPersist = Object.assign({}, values)
this.relation.hydrateForPersistance(this.parent, valuesToPersist)
return this.relation.relatedModel().create(valuesToPersist, { client: trx })
})
}

Expand All @@ -104,9 +97,12 @@ export class HasOneQueryClient implements HasOneClientContract<HasOne, LucidMode
this.parent.$trx = trx
await this.parent.save()

return this.relation.relatedModel().firstOrCreate(Object.assign({
[this.relation.foreignKey]: this.getForeignKeyValue(this.parent, 'firstOrCreate'),
}, search), savePayload, { client: trx })
const valuesToPersist = Object.assign({}, search)
this.relation.hydrateForPersistance(this.parent, valuesToPersist)

return this.relation
.relatedModel()
.firstOrCreate(valuesToPersist, savePayload, { client: trx })
})
}

Expand All @@ -121,9 +117,12 @@ export class HasOneQueryClient implements HasOneClientContract<HasOne, LucidMode
this.parent.$trx = trx
await this.parent.save()

return this.relation.relatedModel().updateOrCreate(Object.assign({
[this.relation.foreignKey]: this.getForeignKeyValue(this.parent, 'updateOrCreate'),
}, search), updatePayload, { client: trx })
const valuesToPersist = Object.assign({}, search)
this.relation.hydrateForPersistance(this.parent, valuesToPersist)

return this.relation
.relatedModel()
.updateOrCreate(valuesToPersist, updatePayload, { client: trx })
})
}
}
12 changes: 10 additions & 2 deletions src/Orm/Relations/HasOne/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
* file that was distributed with this source code.
*/

import { LucidRow, LucidModel } from '@ioc:Adonis/Lucid/Model'
import { QueryClientContract } from '@ioc:Adonis/Lucid/Database'
import { OneOrMany } from '@ioc:Adonis/Lucid/DatabaseQueryBuilder'
import { LucidRow, LucidModel, ModelObject } from '@ioc:Adonis/Lucid/Model'

import {
RelationOptions,
HasOne as ModelHasOne,
Expand All @@ -18,7 +19,7 @@ import {

import { KeysExtractor } from '../KeysExtractor'
import { HasOneQueryClient } from './QueryClient'
import { ensureRelationIsBooted } from '../../../utils'
import { ensureRelationIsBooted, getValue } from '../../../utils'

/**
* Manages loading and persisting has one relationship
Expand Down Expand Up @@ -163,4 +164,11 @@ export class HasOne implements HasOneRelationContract<LucidModel, LucidModel> {
ensureRelationIsBooted(this)
return HasOneQueryClient.eagerQuery(client, this, parent)
}

/**
* Hydrates values object for persistance.
*/
public hydrateForPersistance (parent: LucidRow, values: ModelObject | LucidRow) {
values[this.foreignKey] = getValue(parent, this.localKey, this, 'persist')
}
}
Loading

0 comments on commit e443b20

Please sign in to comment.