@adonisjs/ route- model- 绑定
导言
将路由参数与 Lucid 模型捆绑并自动查询数据库
路由模型绑定是从您的代码库中去掉单行道 Lucid 查询,并在HTTP请求时使用常规查询数据库的通畅方式.
在下面的例子中,我们连接路线参数 :post 财务报告和审定财务报表 :comments 二、缔约国接受的论点 show 方法.
- 来自 URL 的第一个参数的值将用来查询第一个输入的提示模型
show方法(即员额). - 同样地,第二段的值将被用于查询第二个被打入提示的模型(即注释).
说明: 参数和模型使用它们出现的顺序而不是名称来连接. 这是因为TypeScript装饰器无法知道一种方法接受的参数的名称.
// Routes file
import router from '@adonisjs/core/services/router'
const PostsController = () => import('#controllers/posts_controller')
router.get('/posts/:post/comments/:comment', [PostsController, 'show'])
// Controller
import { bind } from '@adonisjs/route-model-binding'
import Post from '#models/post'
import Comment from '#models/comment'
export default class PostsController {
@bind()
async show({}, post: Post, comment: Comment) {
return { post, comment }
}
}
▶️: 你是视觉学习者吗检查出 这些屏幕播放器 了解路由模型的装订、设置和使用.
设置
从 npm 登记册中安装软件包如下 .
npm i @adonisjs/route-model-binding
# yarn lovers
yarn add @adonisjs/route-model-binding
接下来,通过运行以下 A 命令来配置软件包.
node ace configure @adonisjs/route-model-binding
最后一步是登记 RmbMiddleware 内部 start/kernel.ts 文档.
import router from '@adonisjs/core/services/router'
router.use([
// ...other middleware
() => import('@adonisjs/route-model-binding/rmb_middleware'),
])
基本用途
从最基本的例子开始,然后调整复杂程度,为不同的使用案例服务.
在下面的例子中,我们将约束 Post 第一个参数的模型 posts/:id 路线.
import router from '@adonisjs/core/services/router'
const PostsController = () => import('#controllers/posts_controller.js')
router.get('/posts/:id', [PostsController, 'show'])
import { bind } from '@adonisjs/route-model-binding'
import Post from '#models/post'
export default class PostsController {
@bind()
async show({}, post: Post) {
return { post }
}
}
参数和模型按定义顺序相匹配. 因此URL中的第一个参数与控制器方法中的第一个打入型号相匹配.
由于TypeScript装饰器无法读取,因此不使用控制器方法参数的名称来进行匹配(因此技术限制让我们只能使用以订单为基础的匹配).
更改查找密钥
默认情况下,该模型的主键用于在数据库中找到匹配行. 你要么改变全球,要么改变它 只是为了一个特定路线.
通过模型在全球更改搜索键
以下更改后,将使用 slug 属性而不是主键。 简而言之 Post.findByOrFail('slug', value) 查询已执行 .
class Post extends BaseModel {
static routeLookupKey = 'slug'
}
更改单一路径的搜索密钥 .
在下面的例子中,我们直接定义了括号所包围的路由上的查找键.
import router from '@adonisjs/core/services/router'
const PostsController = () => import('#controllers/posts_controller')
router.get('/posts/:id(slug)', [PostsController, 'show'])
你注意到我们的路线 读起来有点好笑吗?
该段落写为 :id(slug),但翻译不善。 因此,随着路由模型的约束,我们建议使用模型名称作为路由参数,因为我们不处理 id 现在 我们正在从数据库中获取模型实例.
遵循是写同样路线的更好方法.
import router from '@adonisjs/core/services/router'
const PostsController = () => import('#controllers/posts_controller')
router.get('/posts/:post(slug)', [PostsController, 'show'])
更改查询逻辑
您可以通过定义静态来改变搜索逻辑 findForRequest 模型本身上的方法。 该方法获得以下参数.
ctx- 当前请求的 HTTP 上下文param- 解析参数。 该参数具有以下属性.param.name- 参数的正统名称.param.param- 路线上定义的参数的原名.param.scoped- 狦true,该参数必须被扩展至其母模型.param.lookupKey- 在路线或模型上定义的查找键.param.parent- 家长代表的名字.
value- 本次请求中的参数值.
在下面的例子中,我们只查询已发表的文章。 另外,确保这种方法要么返回模型实例,要么提出例外.
class Post extends BaseModel {
static findForRequest(ctx, param, value) {
const lookupKey = param.lookupKey === '$primaryKey' ? 'id' : param.lookupKey
return this
.query()
.where(lookupKey, value)
.whereNotNull('publishedAt')
.firstOrFail()
}
}
范围参数
在使用被嵌入的路由资源时,您可能想要将第二段拓宽为与第一段拓宽的关系.
一个很好的例子就是通过 id 找到一个帖子评论.
这个 posts/1/comments/2 如果注释的后号不是,则应返回404 1。 。 。 .
您可以使用 > 大于标志或著名的 面包屑标志
import router from '@adonisjs/core/services/router'
const PostsController = () => import('#controllers/posts_controller')
router.get('/posts/:post/comments/:>comment', [PostsController, 'show'])
import { bind } from '@adonisjs/route-model-binding'
import Post from '#models/post'
import Comment from '#models/comment'
export default class PostsController {
@bind()
async show({}, post: Post, comment: Comment) {
return { post, comment }
}
}
要使上述例子发挥作用,就必须界定 comments 关系的关系 Post 型号。 关系的类型并不重要.
class Post extends BaseModel {
@hasMany(() => Comment)
declare comments: HasMany<typeof Comment>
}
将参数名称转换为 camelCase我们将使用复数形式和单数形式寻找关系.
自定义关系查询
默认情况下,关系会使用绑定子模型的查找键来获取. 有效执行下列查询.
await parent
.related('relationship')
.query()
.where(lookupKey, value)
.firstOrFail()
不过,您可以通过定义“定义”来自定义浏览 findRelatedForRequest 模型上的方法(注,这不是静态方法).
class Post extends BaseModel {
findRelatedForRequest(ctx, param, value) {
/**
* Have to do this weird dance because of
* https://github.com/microsoft/TypeScript/issues/37778
*/
const self = this as unknown as Post
const lookupKey = param.lookupKey === '$primaryKey' ? 'id' : param.lookupKey
if (param.name === 'comment') {
return self
.related('comments')
.query()
.where(lookupKey, value)
.firstOrFail()
}
}
}
无约束的参数
您通常会有原始值参数, 并且不能与模型相绑定 。 例如 version 是正则字符串值,不使用数据库支持.
import router from '@adonisjs/core/services/router'
const PostsController = () => import('#controllers/posts_controller')
router.get(
'/api/:version/posts/:post',
[PostsController, 'show']
)
你可以代表 version 作为控制器方法上的字符串,我们将不进行数据库搜索。 例如:
import { bind } from '@adonisjs/route-model-binding'
import Post from '#models/post'
class PostsController {
@bind()
async show({}, version: string, post: Post) {}
}
由于路由参数和控制器方法参数的匹配顺序与定义的顺序相同,所以你总是必须打入所有参数.
行为守则
为了确保AdonisJS社区欢迎所有人,请审查和遵守 行为守则。 。 。 .
许可证
AdonisJS 路由模型装订是开源软件,根据 麻省理工学院许可证。 。 。 .