如何使用 find 或 findOrFail 自动加载与 Adonis 的关系?
How to autoload a relationship with Adonis with find or findOrFail?
有没有办法自动加载与 findByOrFail 的关系(或任何其他方法,如 find 等)?
在下面的代码中,未定义方法 with()
。
async show({ params, response }) {
try {
return await Company.findByOrFail('domain', params.id).with('websites')
} catch (error) {
console.error(error)
switch (error.name) {
case 'ModelNotFoundException':
return response.notFound({ message: 'companies_show_not_found' })
default:
return response.badRequest({ message: 'something_went_wrong' })
}
}
}
看起来最干净的解决方案是使用 globalScope
。
class Company extends Model {
static boot() {
super.boot()
this.addGlobalScope(function (builder) {
builder.with('websites')
})
}
websites() {
return this.hasMany('App/Models/Website')
}
}
为什么不直接用这样的查询来做:
await Company.query().where('domain', params.id).with('websites').firstOrFail()
你可以像这样使用关系
async show({ params, response }) {
try {
const relationdata= await Company.findByOrFail('domain', params.id)
return await relationdata.websites().fetch()
} catch (error) {
console.error(error)
switch (error.name) {
case 'ModelNotFoundException':
return response.notFound({ message: 'companies_show_not_found' })
default:
return response.badRequest({ message: 'something_went_wrong' })
}
}
}
Adonis 5 在预定义的生命周期事件期间支持 hooks 运行。
所以理想情况下你可以做这样的事情。
class Company extends Model {
@hasMany()
public static websites: HasMany<typeof Website>
@beforeFetch()
@beforeFind()
public static fetchWebsites(query: ModelQueryBuilderContract<typeof Company>) {
query.preload('websites')
}
}
然后当您获取公司时,结果将包含关系。
Company.all()
{
'name': 'company_name',
'websites': [
{
'name': 'my site',
'url': 'my.site'
}
...
]
}
有没有办法自动加载与 findByOrFail 的关系(或任何其他方法,如 find 等)?
在下面的代码中,未定义方法 with()
。
async show({ params, response }) {
try {
return await Company.findByOrFail('domain', params.id).with('websites')
} catch (error) {
console.error(error)
switch (error.name) {
case 'ModelNotFoundException':
return response.notFound({ message: 'companies_show_not_found' })
default:
return response.badRequest({ message: 'something_went_wrong' })
}
}
}
看起来最干净的解决方案是使用 globalScope
。
class Company extends Model {
static boot() {
super.boot()
this.addGlobalScope(function (builder) {
builder.with('websites')
})
}
websites() {
return this.hasMany('App/Models/Website')
}
}
为什么不直接用这样的查询来做:
await Company.query().where('domain', params.id).with('websites').firstOrFail()
你可以像这样使用关系
async show({ params, response }) {
try {
const relationdata= await Company.findByOrFail('domain', params.id)
return await relationdata.websites().fetch()
} catch (error) {
console.error(error)
switch (error.name) {
case 'ModelNotFoundException':
return response.notFound({ message: 'companies_show_not_found' })
default:
return response.badRequest({ message: 'something_went_wrong' })
}
}
}
Adonis 5 在预定义的生命周期事件期间支持 hooks 运行。
所以理想情况下你可以做这样的事情。
class Company extends Model {
@hasMany()
public static websites: HasMany<typeof Website>
@beforeFetch()
@beforeFind()
public static fetchWebsites(query: ModelQueryBuilderContract<typeof Company>) {
query.preload('websites')
}
}
然后当您获取公司时,结果将包含关系。
Company.all()
{
'name': 'company_name',
'websites': [
{
'name': 'my site',
'url': 'my.site'
}
...
]
}