You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Phoenix多ID路由问题:添加子资源删除路由遇疑

在Phoenix中添加父资源下的子资源删除路由及控制器实现

首先,咱们先搞定路由的添加——你想加的这条删除子资源的路由是可行的,但有个关键细节要注意:路由的匹配顺序。Phoenix是从上到下匹配路由的,所以更具体的路由(带两个参数的)必须放在更通用的路由(只带parent id的)前面,不然会出现匹配错误。

调整后的路由应该是这样:

scope "/parent" do
  # 这条更具体的删除子资源路由要放在前面
  delete "/:id/:child_id", ParentController, :remove_child
  get "/", ParentController, :index
  get "/:id", ParentController, :show
  patch "/:id", ParentController, :update
  delete "/:id", ParentController, :remove
end

接下来是控制器的函数签名——你刚才写的def remove_child(conn, %{"id" => id, "child_id"}) do有个小问题:模式匹配里的键值对必须完整写成"key" => value的形式,不然Elixir会识别不了。正确的签名应该是:

def remove_child(conn, %{"id" => parent_id, "child_id" => child_id}) do
  # 这里编写你的删除逻辑,举个简单的例子:
  parent = Parent.get!(parent_id)
  child = Parent.get_associated_child!(parent, child_id) # 假设你有这个获取子资源的函数

  with {:ok, _deleted_child} <- Parent.delete_child(parent, child) do
    conn
    |> put_flash(:info, "子资源删除成功!")
    |> redirect(to: Routes.parent_path(conn, :show, parent_id))
  end
end

另外,如果你想更贴合Phoenix的RESTful风格,其实可以用嵌套资源的写法,这样路由助手会更规范,也不用手动操心顺序:

scope "/" do
  resources "/parents", ParentController do
    # 这里的as: :child会生成对应的路由助手,比如Routes.parent_child_path/4
    delete "/children/:child_id", ParentController, :remove_child, as: :child
  end
end

用这种嵌套写法的话,调用路由的时候就可以用Routes.parent_child_path(conn, :delete, parent.id, child.id),可读性更强。

最后提醒一句:不管用哪种写法,都要确保你的业务逻辑里做了权限校验——比如确认当前用户有权限删除这个父资源下的子资源,避免越权操作。

内容的提问来源于stack exchange,提问作者Sardoan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:36:53