Rails中post_delete_path发送GET而非DELETE请求的问题及解决
帖子删除请求错误及解决方法
关联评论与帖子后,调用删除接口时发送了GET请求而非DELETE请求,报错:No route matches [DELETE] "/delete_post.3"。
相关代码
路由文件(routes.erb)
Rails.application.routes.draw do #get 'posts/index' resources :posts do resources :comments, only: [:destroy, :create] end delete'/delete_post', to: 'posts#destroy' resources :likes, only: [:destroy, :create] resources :sessions, only: [:create, :destroy] get 'sessions/new' get 'sing_in', to: 'sessions#new' get 'sign_out', to: 'sessions#destroy' resources :users, only: [:create, :destroy] get 'users/new' get '/register', to: 'users#new' root 'posts#index' end
Posts控制器
class PostsController < ApplicationController before_action :ensure_user before_action :correct_user, only: [:edit, :update, :destroy] def index @posts = Post.all.order("created_at DESC") end def show @post = Post.find(params[:id]) end def new @post = current_user.posts.new end def create @post = current_user.posts.new(post_params) if @post.save redirect_to post_url(@post) else render 'new', notice: "Couldn't create the post!" end end def edit @post = set_post end def update @post = current_user.posts.find(params[:id]) if @post.update(post_params) redirect_to post_url(@post) else redirect_to post_url(@post), notice: "Couldn't update the post!" end end def destroy @post = current_user.posts.find([params[:id]]) if @post.destroy redirect_to posts_path, notice: "Post has been deleted!" else redirect_to post_url(@post), notice: "Couldn't delete the post!" end end private def correct_user @post = current_user.posts.find_by(id: params[:id]) redirect_to root_path, notice: "You are not authorized to edit this post!" if @post.nil? end def set_post return Post.find(params[:id]) end def post_params params.require(:post).permit(:title, :content) end end
视图中的删除按钮(帖子详情页)
<%= button_to 'Delete', delete_post_path(@post), method: :delete %>
注:已尝试将删除路径定义在posts资源下、切换button_to与link_to,均无效果,指定DELETE路由后仍无法匹配。
最终解决方案
经排查,问题根源有两点:
路由定义冗余且错误:已经通过
resources :posts生成了标准的RESTful路由,额外自定义的delete'/delete_post'路由不符合规范,导致路径匹配异常。需移除该自定义路由,改用RESTful标准的post_path(@post)配合method: :delete生成正确的删除请求路径。关联数据外键约束冲突:删除带有评论或点赞的帖子时,由于comments和likes表的post_id字段设置为非空,直接删除帖子会触发NotNullViolation错误。需在destroy方法中先清除关联的点赞和评论,再删除帖子。修正后的destroy方法如下:
def destroy @post = current_user.posts.find(params[:id]) @post.likes.destroy_all @post.comments.destroy_all if @post.destroy redirect_to posts_path, notice: "Post has been successfully deleted!" else redirect_to @post flash[:notice] = "Can't delete the post!" end end
内容的提问来源于stack exchange,提问作者Tomax47
相关产品推荐
相关产品推荐

