TBD asciinema
- Elegant api (Inspired by Rails ActiveRecord and Laravel Eloquent)
- Uses convention over configuration
- Declarative model definition (scopes, relations, validations etc.)
- Model validation
- Transactions (based on async hooks, so you dont need to wrap your code into callback)
- Based on knex.js (so you have all power of knex query builder)
- Yaml fixtures for seeding test data and using it in tests
- Cascade saving?
- Finite state machine included
- Easy polymorphic relations
npm install @jougene/noar
You dont need to create some example for your own.
Clone repository, run npm install
And use on of existing examples from directory ./examples
For example run:
npm run examples:payments:repl
And work with example models:
- User, UserPersonal, Payment
noar#> await User.find(1)
noar#> await User.all()
noar#> await User.first()
noar#> user = await User.create({ name: 'test', email: 'ivan@gmail.com' })
noar#> await Payment.new().with('user')
noar#> await Payment.with('user').charged()
const Model = require('@jougene/noar')
class User extends Model {
static table = 'users' // dont really need, by default it is pluralized form of model name.
}
const Model = require('@jougene/noar')
class User extends Model {
static table = 'users'
static defaults = { status: 'new' }
}
For now there is 3 types of relations:
- hasOne
- hasMany
- belongsTo (inverted of hasMany)
Imagine you develop some system handling payments.
So you have at least two models: User
and Payment
User has many payments and one payment belongs only to one user
So your models should look like this
class User extends Model {
static table = 'users'
static get relations () {
return {
payments: { hasMany: Payment },
}
}
}
class Payment extends Model {
static table = 'payments'
static get relations () {
return {
user: { belongsTo: User }
}
}
}
- With constructor and
save()
method
const user = new User({ name: 'Ivan', email: 'ivansuper@gmail.com' })
await user.save()
- With static
create
await User.create({ name: 'Ivan', email: 'ivansuper@gmail.com' })
await User.all()
await User.first()
await User.find(42)
await User.where({ status: new })
If you want to get some model with related objects you can use static with
method of model
const userWithPayments = await User.with('payments').first()
Very often you want to have some predefined queries, for example for statuses
await User.where({ status: 'registered' })
await User.where({ status: 'wait_for_email' })
For this case you can use model scopes:
class User extends Model {
static table = 'users'
static scopes = {
registered: (qb) => qb.where({ status: 'registered' }),
waitForEmail: (qb) => qb.where({ status: 'wait_for_email' }),
}
}
And instead of always writing await User.where({ status: 'registered' })
Do this with scopes await User.registered()
caused the same result
TBD
await Transaction.start()
... code
TBD Add all models to your custom repl
Noar.augmentRepl(repl.Context)