Skip to content

Commit

Permalink
feat(model): implement attributes static getter in model class
Browse files Browse the repository at this point in the history
  • Loading branch information
jlenon7 committed Nov 10, 2022
1 parent 0e82b81 commit 999e662
Show file tree
Hide file tree
Showing 12 changed files with 115 additions and 8 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@athenna/database",
"version": "1.2.9",
"version": "1.3.0",
"description": "The Athenna database handler for SQL/NoSQL.",
"license": "MIT",
"author": "João Lenon <lenon@athenna.io>",
Expand Down
2 changes: 1 addition & 1 deletion src/Database/Builders/QueryBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ export class QueryBuilder {
/**
* Create data or update if already exists.
*
* @param {any | any[]} data
* @param {any} data
* @param {string} [primaryKey]
* @return {Promise<any | any[]>}
*/
Expand Down
2 changes: 1 addition & 1 deletion src/Drivers/MySqlDriver.js
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ export class MySqlDriver {
/**
* Create data or update if already exists.
*
* @param {any | any[]} data
* @param {any} data
* @param {string} [primaryKey]
* @return {Promise<any | any[]>}
*/
Expand Down
2 changes: 1 addition & 1 deletion src/Drivers/PostgresDriver.js
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ export class PostgresDriver {
/**
* Create data or update if already exists.
*
* @param {any | any[]} data
* @param {any} data
* @param {string} [primaryKey]
* @return {Promise<any | any[]>}
*/
Expand Down
9 changes: 9 additions & 0 deletions src/Models/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ export class Model {
return 'id'
}

/**
* Set the default attributes of your model.
*
* @return {Record<string, any>}
*/
static get attributes() {
return {}
}

/**
* The attributes that could be persisted in database.
*
Expand Down
40 changes: 38 additions & 2 deletions src/Models/ModelQueryBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,16 @@ export class ModelQueryBuilder {
}
}

const attributes = this.#Model.attributes

Object.keys(attributes).forEach(key => {
if (data[key]) {
return
}

data[key] = attributes[key]
})

return this.#generator.generateOne(await this.#QB.create(data))
}

Expand All @@ -234,13 +244,29 @@ export class ModelQueryBuilder {
data = this.#fillable(data)
}

return this.#generator.generateMany(await this.#QB.createMany(data))
const executor = data => {
const attributes = this.#Model.attributes

Object.keys(attributes).forEach(key => {
if (data[key]) {
return
}

data[key] = attributes[key]
})

return data
}

return this.#generator.generateMany(
await this.#QB.createMany(data.map(executor)),
)
}

/**
* Create or update models in database.
*
* @param data {any | any[]}
* @param data {any}
* @param {boolean} ignorePersistOnly
* @return {Promise<any | any[]>}
*/
Expand All @@ -249,6 +275,16 @@ export class ModelQueryBuilder {
data = this.#fillable(data)
}

const attributes = this.#Model.attributes

Object.keys(attributes).forEach(key => {
if (data[key]) {
return
}

data[key] = attributes[key]
})

return this.#generator.generateOne(await this.#QB.createOrUpdate(data))
}

Expand Down
7 changes: 7 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,13 @@ export class Model {
*/
static get primaryKey(): string

/**
* Set the default attributes of your model.
*
* @return {Record<screen, any>}
*/
static get attributes(): Record<string, any>

/**
* The attributes that could be persisted in database.
*
Expand Down
12 changes: 12 additions & 0 deletions tests/Stubs/models/ProductMySql.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@ export class ProductMySql extends Model {
return 'products'
}

/**
* Set the default attributes of your model.
*
* @return {Record<string, any>}
*/
static get attributes() {
return {
name: this.faker.commerce.productName(),
price: this.faker.commerce.price(),
}
}

/**
* The attributes that could be persisted in database.
*
Expand Down
12 changes: 12 additions & 0 deletions tests/Stubs/models/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@ import { Model, Column, Relation } from '#src/index'
import { Product } from '#tests/Stubs/models/Product'

export class User extends Model {
/**
* Set the default attributes of your model.
*
* @return {Record<string, any>}
*/
static get attributes() {
return {
name: this.faker.name.fullName(),
email: this.faker.internet.email(),
}
}

/**
* The attributes that could be persisted in database.
*
Expand Down
15 changes: 15 additions & 0 deletions tests/Unit/Models/ProductModelTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -398,4 +398,19 @@ test.group('ProductModelTest', group => {

assert.lengthOf(groupByProducts, 10)
})

test('should be able to create product and products using default attributes', async ({ assert }) => {
const product = await ProductMySql.create({ name: 'Hello 1' })
const products = await ProductMySql.createMany([{ name: 'Hello 2' }, {}])

assert.isDefined(product.id)
assert.notDeepEqual(product.price, 0)
assert.deepEqual(product.name, 'Hello 1')

products.forEach(product => {
assert.isDefined(product.id)
assert.isDefined(product.name)
assert.notDeepEqual(product.price, 0)
})
})
})
16 changes: 16 additions & 0 deletions tests/Unit/Models/UserModelTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -418,4 +418,20 @@ test.group('UserModelTest', group => {

assert.lengthOf(groupByUsers, 10)
})

test('should be able to create user and users using default attributes', async ({ assert }) => {
const user = await User.query().select('*').create({ name: 'Hello 1' })
const users = await User.query()
.select('*')
.createMany([{ name: 'Hello 2' }, {}])

assert.isDefined(user.id)
assert.isDefined(user.email)
assert.deepEqual(user.name, 'Hello 1')

users.forEach(user => {
assert.isDefined(user.id)
assert.isDefined(user.email)
})
})
})

0 comments on commit 999e662

Please sign in to comment.