如何让AdonisJS一对多关联模型查询结果扁平化更易使用?
解决AdonisJS Model关联字段扁平化问题
首先明确:你提到每个Buyer对应一个分类,所以需要先在Buyer模型中定义一对一关联(belongsTo),而非之前的一对多products关联。以下是两种简洁的Model层面实现方式:
方式一:直接关联查询(最简洁)
通过Model的Query Builder结合join,直接将分类字段查询到Buyer结果的顶层,无需后续处理:
1. 确保Buyer模型的关联定义
// app/Models/Buyer.js import { BaseModel, belongsTo, BelongsTo } from '@adonisjs/lucid/orm' import Category from './Category.js' export default class Buyer extends BaseModel { // 定义Buyer的字段 public static columns = [ 'id', 'buyer_name', 'description', 'category_id' // 关联Category的外键 ] @belongsTo(() => Category) public category: BelongsTo<typeof Category> }
2. 执行查询
const buyers = await Buyer.query() .select( 'buyers.id', 'buyers.buyer_name', 'buyers.description', 'categories.id as category_id', 'categories.name as category_name' ) .join('categories', 'buyers.category_id', '=', 'categories.id') .orderBy('buyers.buyer_name', 'desc') // 返回的buyers数组就是你需要的扁平化结构
方式二:利用Model序列化自动处理
如果需要保留Model关联的灵活性,同时返回扁平化结构,可以通过自定义Model的序列化方法实现:
1. 完善Buyer模型的序列化逻辑
// app/Models/Buyer.js import { BaseModel, belongsTo, BelongsTo } from '@adonisjs/lucid/orm' import Category from './Category.js' export default class Buyer extends BaseModel { public static columns = [ 'id', 'buyer_name', 'description', 'category_id' ] @belongsTo(() => Category) public category: BelongsTo<typeof Category> // 自定义序列化,将category字段移到顶层 serialize() { const serialized = super.serialize() if (serialized.category) { // 将分类字段提取到顶层 serialized.category_id = serialized.category.id serialized.category_name = serialized.category.name // 删除嵌套的category对象 delete serialized.category } return serialized } }
2. 预加载分类并查询
const buyers = await Buyer.query() .select('id', 'buyer_name', 'description') .preload('category', (query) => { query.select('id', 'name as category_name') }) .orderBy('buyer_name', 'desc') // 序列化后自动得到扁平化结构
内容的提问来源于stack exchange,提问作者positive developer
相关产品推荐
相关产品推荐

