Buffalo 的 generate resource 命令不支持嵌套资源,需手动在 routes.go 中通过 Scope 注册嵌套路由,并修改 handler、模板及 ORM 关联逻辑以透传和校验 post_id。

buffalo generate resource 不支持嵌套资源
Buffalo 官方 buffalo generate resource 命令**不提供 --parent、--nested 或类似参数**,无法直接生成如 /posts/1/comments 这类嵌套路由。它只生成扁平资源(/comments),所有 handler 都在 actions/comments.go 中,与父资源无代码级绑定。
手动添加嵌套路由需改 config/routes.go
嵌套逻辑必须靠人工注册:打开 config/routes.go,在 app.Resource("/posts", PostsResource{}) 之后,显式追加子路由:
app.Resource("/posts", PostsResource{})
app.Scope("/posts/{post_id}", func(app buffalo.App) {
app.Resource("/comments", CommentsResource{})
})
注意两点:
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
-
{post_id}是路径参数,会自动注入到c.Param("post_id"),但CommentsResource的Show、Create等 handler 不会自动感知它——你得在每个 handler 里手动取值并查关联记录 - 生成的
actions/comments.go仍按扁平逻辑写,比如Index默认查全部 comments;你要改成db.Where("post_id = ?", c.Param("post_id")).All(&comments)
嵌套资源的 handler 需要自己补全关联逻辑
生成器创建的 CommentsResource 没有父级上下文,所以这些地方必须手改:
-
Create:不能直接tx.Create(&c),得先查Post是否存在,并把c.Param("post_id")赋给c.PostID字段再插入 -
New和Edit:模板里需要渲染post_id到表单隐藏域或 URL query,否则提交时丢失上下文 -
Destroy:删前应校验该 comment 是否属于指定 post,避免越权删除 - 如果用 pop ORM,建议在
models/comment.go加PostID uint字段和Post *Post `has_one:"posts"`关联,否则查询时得手动 join
别指望模板自动适配嵌套路径
buffalo generate resource 生成的 templates/comments/ 下所有 HTML 模板(如 index.plush.html)里的链接都默认指向 /comments,不会变成 /posts/1/comments。你得逐个改:
-
<a href="<%=%20commentsPath()%20%>"></a>→ 改成<a href="<%=%20postCommentsPath(%7Bpost_id:%20post.ID%7D)%20%>"></a> - 表单
<form action="<%=%20commentsPath()%20%>"></form>→ 改成<form action="<%=%20postCommentsPath(%7Bpost_id:%20post.ID%7D)%20%>"></form> - 所有
commentsPath()辅助函数调用,都要换成带post_id参数的变体,否则路由匹配失败返回 404
真正麻烦的不是写几行路由,而是整个资源生命周期里父 ID 的透传、校验、渲染——Buffalo 不做约定,全靠你一处处补全。


















