Skip to content

Commit

Permalink
refactor(model): update column decorator properties name and behavior
Browse files Browse the repository at this point in the history
serialize now accepts a function.
primary is renamed to isPrimary
serializeAs = null, prevents the column from being serialized
  • Loading branch information
thetutlage committed Jan 12, 2020
1 parent 8cca1d4 commit a607abb
Show file tree
Hide file tree
Showing 13 changed files with 538 additions and 496 deletions.
3 changes: 1 addition & 2 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ The document contains the list of features that must be completed before the alp

- [ ] Complete `ManyToMany.sync` method.
- [ ] Implement `fetchOrCreateMany`, `updateOrCreateMany`, `firstOrCreate` and `updateOrCreate` for all relationships.
- [ ] Add support for default value for `@columns`.
- [ ] Related models aggregrates query.
- [ ] Support for casting columns using a custom function. Both on column and model level.
- [x] Support for serializing columns using a custom function. Both on column and model level.

## Final Release targeting `@adonisjs/core v5`

Expand Down
12 changes: 7 additions & 5 deletions adonis-typings/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,24 +81,26 @@ declare module '@ioc:Adonis/Lucid/Model' {
*/
export type ColumnOptions = {
castAs: string,
serializeAs: string,
serialize: boolean,
primary: boolean,
serializeAs: string | null,
isPrimary: boolean,
hasGetter: boolean,
hasSetter: boolean,
serialize?: (value: any, attribute: string, model: ModelContract) => any,
}

/**
* Represents a computed property on the model
*/
export type ComputedOptions = {
serializeAs: string,
serializeAs: string | null,
}

/**
* Signature for decorator functions
*/
export type ColumnDecorator = (options?: Partial<ColumnOptions>) => (target, property) => void
export type ColumnDecorator = (
options?: Partial<Omit<ColumnOptions, 'hasGetter' | 'hasSetter'>>,
) => (target, property) => void
export type ComputedDecorator = (options?: Partial<ComputedOptions>) => (target, property) => void

/**
Expand Down
2 changes: 1 addition & 1 deletion adonis-typings/relations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ declare module '@ioc:Adonis/Lucid/Relations' {
relatedModel: (() => ModelConstructorContract),
localKey?: string,
foreignKey?: string,
serializeAs?: string,
serializeAs?: string | null,
}

/**
Expand Down
54 changes: 37 additions & 17 deletions src/Orm/BaseModel/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,20 +249,20 @@ export class BaseModel implements ModelContract {
const descriptor = Object.getOwnPropertyDescriptor(this.prototype, name)

const column: ColumnOptions = {
primary: options.primary || false,
isPrimary: options.isPrimary || false,
castAs: options.castAs || this.$configurator.getCastAsKey(this, name),
hasGetter: !!(descriptor && descriptor.get),
hasSetter: !!(descriptor && descriptor.set),
serializeAs: options.serializeAs || this.$configurator.getSerializeAsKey(this, name),
serialize: (options.serialize === undefined || options.serialize === null)
? this.$configurator.serialize(this, name)
: options.serialize,
serializeAs: options.serializeAs !== undefined
? options.serializeAs
: this.$configurator.getSerializeAsKey(this, name),
serialize: options.serialize,
}

/**
* Set column as the primary column, when `primary` is to true
*/
if (column.primary) {
if (column.isPrimary) {
this.$primaryKey = name
}

Expand Down Expand Up @@ -1221,30 +1221,50 @@ export class BaseModel implements ModelContract {
* Converting model to it's JSON representation
*/
public serialize () {
const Model = this.constructor as typeof BaseModel
const Model = this.constructor as ModelConstructorContract
const results = {}

/**
* Serializing attributes
*/
Object.keys(this.$attributes).forEach((key) => {
const column = Model.$getColumn(key)!
if (column.serialize) {
results[column.serializeAs] = this.$attributes[key]
if (!column.serializeAs) {
return
}

const value = this[key]
results[column.serializeAs] = typeof (column.serialize) === 'function'
? column.serialize(value, key, this)
: value
})

/**
* Serializing relationships
*/
Object.keys(this.$preloaded).forEach((key) => {
const relation = Model.$getRelation(key as any)! as RelationshipsContract
if (!relation.$serializeAs) {
return
}

const value = this.$preloaded[key]
results[relation.$serializeAs] = Array.isArray(value)
? value.map((one) => one.toJSON())
: value.toJSON()
})

/**
* Serializing computed properties as last. This gives the option to re-write
* keys which are defined as attributes or relations.
*/
Model.$computed.forEach((value, key) => {
const computedValue = this[key]
if (computedValue !== undefined) {
if (computedValue !== undefined && value.serializeAs) {
results[value.serializeAs] = computedValue
}
})

Object.keys(this.$preloaded).forEach((key) => {
const relationValue = this.$preloaded[key]
results[Model.$getRelation(key)!.$serializeAs] = Array.isArray(relationValue)
? relationValue.map((one) => one.toJSON())
: relationValue.toJSON()
})

return results
}

Expand Down
18 changes: 9 additions & 9 deletions test/orm/adapter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ test.group('Adapter', (group) => {
class User extends BaseModel {
public static $table = 'users'

@column({ primary: true })
@column({ isPrimary: true })
public id: number

@column()
Expand All @@ -59,7 +59,7 @@ test.group('Adapter', (group) => {
class User extends BaseModel {
public static $table = 'users'

@column({ primary: true })
@column({ isPrimary: true })
public id: number

@column()
Expand Down Expand Up @@ -87,7 +87,7 @@ test.group('Adapter', (group) => {
class User extends BaseModel {
public static $table = 'users'

@column({ primary: true })
@column({ isPrimary: true })
public id: number

@column()
Expand Down Expand Up @@ -115,7 +115,7 @@ test.group('Adapter', (group) => {
class User extends BaseModel {
public static $table = 'users'

@column({ primary: true })
@column({ isPrimary: true })
public id: number

@column()
Expand Down Expand Up @@ -144,7 +144,7 @@ test.group('Adapter', (group) => {
class User extends BaseModel {
public static $table = 'users'

@column({ primary: true })
@column({ isPrimary: true })
public id: number

@column()
Expand Down Expand Up @@ -174,7 +174,7 @@ test.group('Adapter', (group) => {
class User extends BaseModel {
public static $table = 'users'

@column({ primary: true })
@column({ isPrimary: true })
public id: number

@column()
Expand Down Expand Up @@ -204,7 +204,7 @@ test.group('Adapter', (group) => {
class User extends BaseModel {
public static $table = 'users'

@column({ primary: true })
@column({ isPrimary: true })
public id: number

@column()
Expand All @@ -229,7 +229,7 @@ test.group('Adapter', (group) => {
class User extends BaseModel {
public static $table = 'users'

@column({ primary: true })
@column({ isPrimary: true })
public id: number

@column()
Expand Down Expand Up @@ -261,7 +261,7 @@ test.group('Adapter', (group) => {
class User extends BaseModel {
public static $table = 'users'

@column({ primary: true })
@column({ isPrimary: true })
public id: number

@column()
Expand Down
Loading

0 comments on commit a607abb

Please sign in to comment.