ORM written in Typescript, inspired by Laravel Eloquent, supports Mongodb/Mongoose.
Warning: This is a documentation for v0.4.x, if you are using v0.3.x please checkout readme for v0.3.x in here.
If you are Laravel Eloquent lover and want to use it in Node JS
you will love Najs Eloquent
. Najs Eloquent
is Laravel Eloquent, written in Typescript
.
Add najs-binding
, najs-eloquent
yarn add najs-binding najs-eloquent
or
npm install najs-binding najs-eloquent
That's it.
NajsEloquent runs with Memory driver by default that means all data is saved in memory. There are some available drivers that you can use
I'm writing detail documentation, please try the library and give me a hand if you can.
Simply create new class extends from a Model
class
import { Model } from 'najs-eloquent'
export class User extends Model {
// define a property belongs to User model
email: string
// define a class name which used for Dependency injection
// (this feature provided by "najs-binding" package)
getClassName() {
return 'YourNamespace.User'
}
}
// Register the User class
Model.register(User)
You can query entries from database via static Query or instance query via .newQuery()
.
Retrieve entries via static query
const result = await User.where('id', '>', 10).get()
Retrieve entries via instance query
const result = new User()
.newQuery()
.where('id', '>', 10)
.get()
You can build grouped query via sub-query, like this
// a = 1 AND (b = 2 OR c = 3)
const result = await User.where('a', 1)
.where(function(subQuery) {
subQuery.where('b', 2).orWhere('c', 3)
})
.get()
All querying functions support auto-completed/auto-suggestion to help you prevent any typo mistake. If you are familiar with Laravel Query Builder you can start write query without learning anything.
Create new model
const user = new User()
user.email = 'email@test.com'
await user.save()
Update a model
const user = await User.firstOrFail('id')
user.email = 'email@test.com'
await user.save()
Delete a model
const user = await User.firstOrFail('id')
await user.delete()
// or you can use query builder
await User.where('id', 'deleted-id').delete()
You can define an accessor by getter
or a function like Laravel Eloquent
// file: Accessor.ts
import { Model } from 'najs-eloquent'
export class User extends Model {
get full_name() {
return this.attributes['first_name'] + ' ' + this.attributes['last_name']
}
// Laravel Eloquent style, available for node > 6.x
// If you define this function AND getter, this function will be skipped
getFullNameAttribute() {
return this.attributes['first_name'] + ' ' + this.attributes['last_name']
}
}
You can define a mutator by setter
or a function like Laravel Eloquent
// file: Mutator.ts
import { Model } from 'najs-eloquent'
export class User extends Model {
set full_name(value: any) {
// ...
}
// Laravel Eloquent style, available for node > 6.x
// If you define this function AND setter, this function will be skipped
setFullNameAttribute(value: any) {
// ...
}
}
fillable
& guarded
Just like Laravel, you can define mass assignable fields by fillable
or guarded
property
export class User extends Model {
protected fillable = ['email', 'username']
// This way also works :)
// static fillable = ['email', 'username']
}
Only defined properties in fillable can be filled with .fill()
const user = new User()
user.fill({ email: 'a', password: 'x' })
console.log(user.toObject()) // => { email: a }
You can skip fillable
setting by using .forceFill()
visible
& hidden
You can define serialized fields by visible
or hidden
property
export class User extends Model {
protected fillable = ['email', 'username']
protected hidden = ['password']
// This way also works :)
// static hidden = ['password']
}
When using .toObject()
or .attributesToObject()
the password
field will be skipped
const user = new User()
user.forceFill({ email: 'a', password: 'x' })
console.log(user.toObject()) // => { email: a }
timestamps
You can simply define timestamps for models by changing static (or protected) variable named timestamps
. By using this feature every time the model get saved, created_at
and updated_at
will updated automatically
export class User extends Model {
protected timestamps = true
// This way also works :)
// static timestamps = true
}
By default, Najs Eloquent will create 2 fields named created_at
and updated_at
, you can custom the fields' name:
export class User extends Model {
protected timestamps = { createdAt: 'created', updatedAt: 'updated' }
// This way also works :)
// static timestamps = { createdAt: 'created', updatedAt: 'updated' }
}
softDeletes
You can simply define soft deletes feature for models by changing static (or protected) variable named softDeletes
.
export class User extends Model {
protected softDeletes = true
// This way also works :)
// static softDeletes = true
}
By using this feature every time the model get deleted the data ind database not actually deleted, it update deleted_at
from null
to date object. You can custom the deleted_at
field name:
export class User extends Model {
protected softDeletes = { deletedAt: 'deleted' }
// This way also works :)
// static softDeletes = { deletedAt: 'deleted' }
}
With soft deletes model all retrieve operators like find()
or get()
automatically return non-deleted entries only, you can use .withTrashed()
or .onlyTrashed()
to receive deleted entries
const users = await User.withTrashed().get()
You can listen to events creating
, created
, saving
, saved
, updating
, updated
, deleting
, deleted
, restoring
, restored
by using .on()
or just trigger for 1 event only by .once()
. All event listener is async
const user = new User()
user.on('created', async function(createdModel: User) {
// ...
})
user.email = '...'
user.save()
You can listen to global event like this
User.on('created', function(createdModel: any) {
// ...
})
najs-eloquent
supports HasOne
, HasMany
, ManyToMany
, MorphOne
and MorphMany
relationships. This feature doesn't look like Laravel. We couldn't give the same name the data and relation in Typescript, then you have to separate it
import { Model, HasMany, BelongsTo } from 'najs-eloquent'
class User extends Model {
// Define property "posts" which receive data from relation "postsRelation"
posts: HasMany<Post>
// Define property "postsRelation" which handle this relationship
get postsRelation() {
return this.defineRelation('posts').hasMany(Post)
}
}
class Post extends Model {
// define property which is foreign key and point to User model
user_id: string
// Inverse relation data property
user: BelongsTo<User>
// Define inverse relation
get userRelation() {
return this.defineRelation('user').belongsTo(User)
}
}
So we can assign new Post to user like this
const post = new Post()
const user = new User()
user.postsRelation.associate(post)
// when you save the user model, post will be saved and associate to User automatically
await user.save()
// eager load posts when loading users
const result = await User.with('posts').firstOrFail()
console.log(result.posts) // a collection of posts belongs to current user
// lazy load posts from user
await user.postsRelation.lazyLoad()
// or just load relation, najs-eloquent uses eager loading if possible
await user.load('posts')
I'm writing detail documentation, please try the library and give me a hand if you can.
najs-eloquent
has Factory feature which use chance
as a faker:
import { Factory, factory } from 'najs-eloquent'
import { User } from 'somewhere...'
// define a factory for User model
Factory.define(User, function(faker, attributes) {
return Object.assign(
{
email: faker.email()
},
attributes
)
})
// create model and save to database by factory()
await factory(User).create()
// make model instance only by factory()
const fakeUser = factory(User).make()
// make 3 model instances by factory()
const fakeUsers = factory(User)
.times(3)
.make()
All classes you need to implement new driver are available in NajsEloquent
object.
I'm writing detail documentation, please try the library and give me a hand if you can.
PRs are welcomed to this project, and help is needed in order to keep up with the changes of Laravel Eloquent. If you want to improve the library, add functionality or improve the docs please feel free to submit a PR.
If you want to become a sponsor please let me know.
You can buy me a beer via Paypal or Patreon.
Thanks in advance!
MIT © Nhat Phan
问题内容: 有没有办法用Laravel的ELOQUENT ORM来“限制”结果? 和雄辩? 问题答案: 创建一个扩展口才的游戏模型,并使用此模型: 这里将获得30条记录,这里将抵消30条记录。 在最新的Laravel版本中,您还可以使用:
问题内容: 我将Oracle用作数据库层,但是问题是通过OCI8(我做了一个PDO用户空间驱动程序)的oracle仅支持SQL语句中的命名参数,不支持定位的参数。(例如使用多个?) 从根本上讲,是Laravel的Eloquent生成了SQL,但是我找不到任何有关如何重写参数构造的文档。 我希望能够以“:name”的形式创建命名参数,而不是放置多个“?” 整个查询。 能做到吗?我的猜测是它与数据库语
问题内容: 目前,我有一个名为的模型类。 我想将帖子分为两种不同的类型;和。我认为做到这一点的最佳方法是通过继承,所以并且会扩展。最佳方法是什么?从哪里开始? 问题答案: 在深入探讨 多表 继承之前,我想谈一谈 单表 继承。当涉及到数据库模型的继承时,单表继承是更简单的方法。 您有多个模型绑定到同一张表,并有一个列来区分不同的模型类。但是,您通常要实现继承的原因是因为模型具有共享的属性,但也具有模
问题内容: 已关闭 。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗? 更新问题,使其仅通过编辑此帖子来关注一个问题。 6个月前关闭。 我在Laravel查询生成器和雄辩者之间进行了一些性能测试。使用各种sql语句(select-update-delete- insert),查询生成器要快得多。 所以我的问题是:为什么有人对普通查询生成器使用Laravel Eloquent? 问题答案
问题内容: 我是Laravel的新手。我正在开发laravel 5应用程序,并且卡在这里。我有2个这样的模型: 消息和用户之间存在多对多关系,因此给我一个数据透视表: 我有这样的SQL查询: 如何将此查询转换为laravel对等词? 问题答案: 下面的代码解决了我的问题:
我正在尝试返回属于文件路由中相同案例的多个会话。php: 控制器:: SessionController.php: 模型类:: LawSession.php: 模型类:: LawCase.php: 我得到了这个错误: 关系方法必须返回类型为照明\数据库\雄辩\关系\关系的对象