ORM for Boldr on top of ObjectionJS with additional utilities for GraphQL
npm install boldr-ormORM for Boldr on top of ObjectionJS with additional utilities for GraphQL
ObjectionJS documentation: http://vincit.github.io/objection.js/
ObjectionJS Repo: https://github.com/Vincit/objection.js/
- Automatically added timestamps
- Table name generated from model name automatically
- Soft delete functionality
- GraphQL helpers
createdAt and updatedAt fields. These fields are managed by Boldr ORM and updated whenever data is added or removed.To disable time stamps:
Add static addTimestamps = false; on to your model.
Two additional helper methods are included for times when you might not want to modify the timestamp.
modify: updates the updatedAt column of the table to current time (new Date().toISOString()). dontModify: keeps the current timestamps in place when the query is executed.
``javascript
class Article extends Model {
static tableName = 'Article';
...
}
class Article extends Model {
...
}
`
to the model. Don't forget your table must contain a
deletedAt column, as a nullable timestamp.
Soft delete enabled models, aren't actually removed when the delete method is called. Instead the value of the
deletedAt column is filled with the current timestamp. Queries don't return data which have a timestamp in the deletedAt field. Helper methods implemented for Soft Delete:
delete: archive or delete a row (depending on whether softDelete is true or false)
archive: archive (soft delete) a row (use delete it's the same thing)
withArchived: return all data regardless of whether or not they been "deleted" or archived.
onlyArchived: return only the data which has been deleted with softDelete enabled.
restore: restore (unarchive) an archived set of data.
forceDelete: actually delete a row from the database If you want to use some other column name instead of
deletedAt you can do static softDelete = 'deleted_at'; `js
class Post extends Model {
// Enable soft delete
static softDelete = true;
}// soft delete
Post.query().where('id', 1).delete();
// restore an archived row
Post.query().where('id', 1).restore();
// get all non-archived posts
Post.query();
// get all posts (including archived / "soft deleted" ones)
Post.query().withArchived();
// retrieve only archived posts
Post.query().onlyArchived();
// completely remove a post from the database
Post.query().forceDelete();
`$3
#### getDeleteByIdResolver()
returns a resolver for GraphQL delete mutation
deleteCategory(id: ID) { DeletedItem }
Mutation: { deleteCategory: Category.getDeleteByIdResolver() }####
getFindByIdSubResolver()
returns a resolver for finding model by id. It optionally takes a propName
argument which denotes the name of the field containing the id.
type Store { id: ID!, name: String!, category: Category}
Query: { Store: { category: Category.getFindByIdSubResolver() } }
Query: { Store: { category: Category.getFindByIdSubResolver('categoryId') } }$3
save: inserts a model if the id column does not exist, otherwise updates it.
saveAndFetch: saves the model and then fetches it.$3
Wraps the where condition till now into braces
so builder.where('a', 'b').orWhere('c', 'd').wrapWhere().where('e', 'f'); becomes "WHERE (a = 'b' OR c = 'd') AND e = 'f'"$3
creates an and (or - or - or) condition
`js
q.where('id', 1).whereByOr({posts: 100, user: 'admin'})
// where id = 1 and (posts = 100 or user = 'admin')
`$3
creates an or (and - and - and) condition
`js
q.where('id', 1).whereByAnd({posts: 100, user: 'admin'})
// where id = 1 or (posts = 100 and user = 'admin')
`$3
find: find is like where except if only a single argument is given, it treats the argument as an id.`js
// all three are equivalent
Person.query().find(1);
Person.query().where('id', 1);
Person.query().findById(1);// both are equivalent
Person.query().find('name', 'John');
Person.query().where('name', 'John');
`$3
Instead of doing Person.query().where() you can do Person.where()
Instead of doing Person.query().find() you can do Person.find() $3
You can define all your relationships in the $relations method.
#### Methods for defining relations
belongsTo(model, options)
hasOne(model, options)
hasMany(model, options)
hasManyThrough(model, options)options are totally optional. they can be:
`
name: name of the relationship (by default name of the model in camelCase)
joinFrom: join field from (by default ModelTableName.camelCasedModelNameId)
joinTo: join field to (by default ModelTableName.id)
filter: apply this filter to the model
through: {
model: if there is a model for the through table
table: tableName of the table to join through
from: join through from
to: join through to
filter: filter to apply on the join table
extra: extra fields to select from the through table
}
``js
class Pet extends Model {
static $relations() {
this.hasOne(Pet);
this.hasMany(Toy, {name: 'toys'});
this.belongsTo(Person);
this.hasManyThrough(Pet, {
name: 'siblings',
through: {
table: 'Pet_Siblings',
from: 'pet_id',
to: 'sibling_id',
},
});
}
}
`Model can be a model object, or an absolute path to a model class. It can also be a relative path if you set the basePath of all models using
Model.setBasePath(path)$3
`js
import {InputError} from 'boldr-orm';async function saveStore(store) {
if (!store.name) {
throw new InputError({
name: 'Name is required',
});
}
}
// Alternatively instead of importing InputError you can simply throw Model.Error
async function saveStore(store) {
if (!store.name) {
throw new Store.Error({
name: 'Name is required',
});
}
}
``