Skip to content

Commit

Permalink
refactor: ensure tableName is statically evaluated (#462)
Browse files Browse the repository at this point in the history
* refactor: ensure tableName is statically evaluated

* chore: make tableName consistent with other model properties

* test: add unit test for .initialize method on model with dynamic tableName
  • Loading branch information
zacharygolba authored Oct 16, 2016
1 parent fd60ff7 commit a343f87
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 23 deletions.
54 changes: 39 additions & 15 deletions src/packages/database/model/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { sql } from '../../logger';
import { saveRelationships } from '../relationship';
import pick from '../../../utils/pick';
import omit from '../../../utils/omit';
import chain from '../../../utils/chain';
import setType from '../../../utils/set-type';
import underscore from '../../../utils/underscore';
import type Logger from '../../logger'; // eslint-disable-line max-len, no-duplicate-imports
Expand All @@ -19,6 +20,15 @@ import getColumns from './utils/get-columns';
import validate from './utils/validate';

class Model {
/**
* The name of the corresponding database table for a `Model` instance's
* constructor.
*
* @property tableName
* @memberof Model
*/
tableName: string;

/**
* The canonical name of a `Model`'s constructor.
*
Expand Down Expand Up @@ -84,6 +94,14 @@ class Model {
*/
static primaryKey: string = 'id';

/**
* The name of the corresponding database table for a `Model`.
*
* @property tableName
* @memberof Model
*/
static tableName: string;

/**
* The canonical name of a `Model`.
*
Expand Down Expand Up @@ -299,21 +317,6 @@ class Model {
}
}

static get tableName(): string {
return pluralize(underscore(this.name));
}

static set tableName(value: string): void {
if (value && value.length) {
Reflect.defineProperty(this, 'tableName', {
value,
writable: false,
enumerable: false,
configurable: false
});
}
}

async save(deep?: boolean): Promise<this> {
const {
constructor: {
Expand Down Expand Up @@ -444,6 +447,27 @@ class Model {
return Promise.resolve(this);
}

if (!this.tableName) {
const tableName = chain(this.name)
.pipe(underscore)
.pipe(pluralize)
.value();

Reflect.defineProperty(this, 'tableName', {
value: tableName,
writable: false,
enumerable: true,
configurable: false
});

Reflect.defineProperty(this.prototype, 'tableName', {
value: tableName,
writable: false,
enumerable: false,
configurable: false
});
}

return initializeClass({
store,
table,
Expand Down
35 changes: 27 additions & 8 deletions src/packages/database/test/model.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,25 +258,44 @@ describe('module "database/model"', () => {
expect(Subject.validates.title).to.be.a('function');
});

it('adds an `modelName` property to the `Model`', () => {
expect(Subject.modelName).to.equal('subject');
it('adds a `modelName` property to the `Model`', () => {
expect(Subject).to.have.property('modelName', 'subject');
});

it('adds an `modelName` property to the `prototype`', () => {
expect(Subject.prototype.modelName).to.equal('subject');
it('adds a `modelName` property to the `prototype`', () => {
expect(Subject).to.have.deep.property('prototype.modelName', 'subject');
});

it('adds an `resourceName` property to the `Model`', () => {
expect(Subject.resourceName).to.equal('subjects');
it('adds a `resourceName` property to the `Model`', () => {
expect(Subject).to.have.property('resourceName', 'subjects');
});

it('adds an `resourceName` property to the `prototype`', () => {
expect(Subject.prototype.resourceName).to.equal('subjects');
it('adds a `resourceName` property to the `prototype`', () => {
expect(Subject)
.to.have.deep.property('prototype.resourceName', 'subjects');
});

it('adds an `initialized` property to the `Model`', () => {
expect(Subject.initialized).to.be.true;
});

describe('- without `tableName`', () => {
class Post extends Model {}

before(async () => {
await Post.initialize(store, () => {
return store.connection(Post.tableName);
});
});

it('adds a `tableName` property to the `prototype`', () => {
expect(Post).to.have.property('tableName', 'posts');
});

it('adds a `tableName` property to the `prototype`', () => {
expect(Post).to.have.deep.property('prototype.tableName', 'posts');
});
});
});

describe('.create()', () => {
Expand Down

0 comments on commit a343f87

Please sign in to comment.