Rails嵌套路由删除post报No route matches缺失[:id]错误如何解决
错误原因分析
报错核心是user_post_path路由需要post的id参数,但你传入的post对象没有id(值为nil),触发路由匹配失败。
根因定位
- 你在
PostsController#create方法中,当@post.save失败时,直接调用render "users/show"渲染用户详情页 - 之前执行的
@post = @user.posts.build(params_post)操作,会把未保存的、无id的@post对象临时加入到@user.posts的关联缓存中 - 视图遍历
@user.posts时,会读取到这个未保存的post对象,生成删除链接时就会抛出缺失id的错误 - 额外隐藏问题:
before_action :set_post的参数拼写错误,expect: [:create]应为except: [:create],否则create动作也会执行set_post,后续会触发找不到params[:id]的报错
解决方案
1. 修复create方法的渲染逻辑
修改create的else分支,重置关联缓存,避免未保存的post被带到视图中:
def create @post = @user.posts.build(params_post) if @post.save flash[:success] = "Post created!" redirect_to user_path(@user) else # 重置@user.posts缓存,清除刚build的未保存对象 @user.reload # 原代码里的@posts = Post.all无实际作用可直接删除,视图用的是@user.posts render "users/show" end end
也可以选择在视图层过滤未保存的对象:
<% @user.posts.each do |post| %> <% next if post.new_record? %> <!-- 原有渲染逻辑保持不变 --> <% end %>
2. 修复before_action的拼写错误
before_action :set_post, except: [:create]
可选优化
如果需要在保存失败时保留用户输入的内容,把未保存的@post单独传给表单组件即可,不要和已保存的posts列表混同处理。
验证方法
修改后提交不符合校验规则的内容触发保存失败,页面不会再报路由错误,会正常展示用户已发布的所有帖子,表单输入的内容也会正常保留。
内容的提问来源于stack exchange,提问作者baim
相关产品推荐
相关产品推荐

