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
相关产品推荐
相关产品推荐

