Security News
38% of CISOs Fear They’re Not Moving Fast Enough on AI
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
@melchyore/adonis-auto-preload
Advanced tools
Auto-preload multiple relationships when retrieving Lucid models
Node.js >= 16.17.0
npm install @melchyore/adonis-auto-preload
# or
yarn add @melchyore/adonis-auto-preload
# or
pnpm install @melchyore/adonis-auto-preload
node ace configure @melchyore/adonis-auto-preload
Extend from the AutoPreload mixin and add a new static $with
attribute.
Adding as const
to $with
array will let the compiler know about your relationship names and infer them so you will have better intellisense when using without
and withOnly
methods.
Relationships will be auto-preloaded for find
, all
and paginate
queries.
// App/Models/User.ts
import { BaseModel, column, hasMany, HasMany } from '@ioc:Adonis/Lucid/Orm'
import { compose } from '@ioc:Adonis/Core/Helpers'
import { AutoPreload } from '@ioc:Adonis/Addons/AutoPreload'
import Post from 'App/Models/Post'
class User extends compose(BaseModel, AutoPreload) {
public static $with = ['posts'] as const
@column({ isPrimary: true })
public id: number
@column()
public email: string
@hasMany(() => Post)
public posts: HasMany<typeof Post>
}
// App/Controllers/Http/UsersController.ts
import User from 'App/Models/User'
export default class UsersController {
public async show() {
return await User.find(1) // ⬅ Returns user with posts attached.
}
}
You can also use functions to auto-preload relationships. The function will receive the model query builder as the only argument.
// App/Models/User.ts
import { BaseModel, column, hasMany, HasMany } from '@ioc:Adonis/Lucid/Orm'
import { compose } from '@ioc:Adonis/Core/Helpers'
import { AutoPreload } from '@ioc:Adonis/Addons/AutoPreload'
import Post from 'App/Models/Post'
class User extends compose(BaseModel, AutoPreload) {
public static $with = [
(query: ModelQueryBuilderContract<typeof this>) => {
query.preload('posts')
}
]
@column({ isPrimary: true })
public id: number
@column()
public email: string
@hasMany(() => Post)
public posts: HasMany<typeof Post>
}
// App/Controllers/Http/UsersController.ts
import User from 'App/Models/User'
export default class UsersController {
public async show() {
return await User.find(1) // ⬅ Returns user with posts attached.
}
}
You can auto-preload nested relationships using the dot "." between the parent model and the child model. In the following example, User
-> hasMany -> Post
-> hasMany -> Comment
.
// App/Models/Post.ts
import { BaseModel, column, hasMany, HasMany } from '@ioc:Adonis/Lucid/Orm'
import { compose } from '@ioc:Adonis/Core/Helpers'
class Post extends BaseModel {
@column({ isPrimary: true })
public id: number
@column()
public userId: number
@column()
public title: string
@column()
public content: string
@hasMany(() => Comment)
public comments: HasMany<typeof Comment>
}
// App/Models/User.ts
import { BaseModel, column, hasMany, HasMany } from '@ioc:Adonis/Lucid/Orm'
import { compose } from '@ioc:Adonis/Core/Helpers'
import { AutoPreload } from '@ioc:Adonis/Addons/AutoPreload'
import Post from 'App/Models/Post'
class User extends compose(BaseModel, AutoPreload) {
public static $with = ['posts.comments'] as const
@column({ isPrimary: true })
public id: number
@column()
public email: string
@hasMany(() => Post)
public posts: HasMany<typeof Post>
}
When retrieving a user, it will preload both posts
and comments
(comments
will be attached to their posts
parents objects).
You can also use functions to auto-preload nested relationships.
public static $with = [
(query: ModelQueryBuilderContract<typeof this>) => {
query.preload('posts', (postsQuery) => {
postsQuery.preload('comments')
})
}
]
The AutoPreload
mixin will add 3 methods to your models. We will explain all of them below.
We will use the following model for our methods examples.
// App/Models/User.ts
import { BaseModel, column, hasOne, HasOne, hasMany, HasMany } from '@ioc:Adonis/Lucid/Orm'
import { compose } from '@ioc:Adonis/Core/Helpers'
import { AutoPreload } from '@ioc:Adonis/Addons/AutoPreload'
import Profile from 'App/Models/Profile'
import Post from 'App/Models/Post'
class User extends compose(BaseModel, AutoPreload) {
public static $with = ['posts', 'profile'] as const
@column({ isPrimary: true })
public id: number
@column()
public email: string
@hasOne(() => Profile)
public profile: HasOne<typeof Profile>
@hasMany(() => Post)
public posts: HasMany<typeof Post>
}
This method takes an array of relationship names as the only argument. All specified relationships will not be auto-preloaded. You cannot specify relationships registered using functions.
// App/Controllers/Http/UsersController.ts
import User from 'App/Models/User'
export default class UsersController {
public async show() {
return await User.without(['posts']).find(1) // ⬅ Returns user with profile and without posts.
}
}
This method takes an array of relationship names as the only argument. Only specified relationships will be auto-preloaded. You cannot specify relationships registered using functions.
// App/Controllers/Http/UsersController.ts
import User from 'App/Models/User'
export default class UsersController {
public async show() {
return await User.withOnly(['profile']).find(1) // ⬅ Returns user with profile and without posts.
}
}
Exclude all relationships from being auto-preloaded.
// App/Controllers/Http/UsersController.ts
import User from 'App/Models/User'
export default class UsersController {
public async show() {
return await User.withoutAny().find(1) // ⬅ Returns user without profile and posts.
}
}
Note
You can chain other model methods with mixin methods. For example,
await User.withoutAny().query().paginate(1)
User
-> hasMany -> Post
-> hasMany -> Comments
. If you auto-preload user
and comments
from Post
and you auto-preload posts
from User
, you will end-up in a infinite loop and your application will stop working.When using route model binding, you cannot use without
, withOnly
and withoutAny
methods in your controller. But, you can make use of findForRequest method.
// App/Models/User.ts
import { BaseModel, column, hasOne, HasOne, hasMany, HasMany } from '@ioc:Adonis/Lucid/Orm'
import { compose } from '@ioc:Adonis/Core/Helpers'
import { AutoPreload } from '@ioc:Adonis/Addons/AutoPreload'
import Profile from 'App/Models/Profile'
import Post from 'App/Models/Post'
class User extends compose(BaseModel, AutoPreload) {
public static $with = ['posts', 'profile'] as const
@column({ isPrimary: true })
public id: number
@column()
public email: string
@hasOne(() => Profile)
public profile: HasOne<typeof Profile>
@hasMany(() => Post)
public posts: HasMany<typeof Post>
public static findForRequest(ctx, param, value) {
const lookupKey = param.lookupKey === '$primaryKey' ? 'id' : param.lookupKey
return this
.without(['posts']) // ⬅ Do not auto-preload posts when using route model binding.
.query()
.where(lookupKey, value)
.firstOrFail()
}
}
npm run test
👤 Oussama Benhamed
Contributions, issues and feature requests are welcome!
Feel free to check issues page. You can also take a look at the contributing guide.
Give a ⭐️ if this project helped you!
Copyright © 2022 Oussama Benhamed.
This project is MIT licensed.
FAQs
Auto-preload multiple relationships when retrieving Lucid models
The npm package @melchyore/adonis-auto-preload receives a total of 0 weekly downloads. As such, @melchyore/adonis-auto-preload popularity was classified as not popular.
We found that @melchyore/adonis-auto-preload demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.
Security News
Company News
Socket is joining TC54 to help develop standards for software supply chain security, contributing to the evolution of SBOMs, CycloneDX, and Package URL specifications.