Tomax47
Tomax47

Reputation: 31

Rails post delete path is assigned to GET method instead of DELETE

After I associated the comments & the posts, the post_delete_path started sending a GET request instead of a Delete one when called, showing the following error : <No route matches [DELETE] "/delete_post.3">

The routes.erb file :

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 Controller :

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

The delete button in the show file in the views for the post :

<%= button_to 'Delete', delete_post_path(@post), method: :delete %>

The route to delete the post with the DELETE request ain't showing, even after specifying it in the routes file : enter image description here

I tried specifying the delete path in the routes under the posts resources, yet it showed the new path with a GET method instead of DELETE.

resources :posts do
    resources :comments, only: [:destroy, :create]
    delete'/post_delete', to: 'posts#destroy'
end
resources :posts do
   resources :comments, only: [:destroy, :create]
end
delete'/post_delete', to: 'posts#destroy'

Also, I tried switching between button_to & link_to, though it ain't help.

UPDATE:

I figured out that what causing the problem were two things, the first was a routing issue, I defined a post_delete route with a get method instead of a delete one, although I have the resources :posts available to use, so I got rid of it. Second, when deleting a post with comments or likes associated with it, I was getting the NotNullViolation error cuz the post_id for comments and likes cant be null, so to overcome this problem, in the destroy function in the post controller, I deleted all of the comments and likes associated with the post before deleting it : ``` 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

Upvotes: 2

Views: 121

Answers (2)

surya narayanan
surya narayanan

Reputation: 56

The thing is that your button is firing the request properly and I think the issue is with the correct_user before action that gets called during destroy.

The probable reason would be your application receives the request for deleting the post and correct_user action starts executing and faces an error. Because of this further actions are stopped that is the request is not passed to the destroy action and the user is redirected to the the location where the request came from.

I found this the above by recreating the scenario and you can confirm the same by either removing the before action for destroy method or fixing the issue in correct_user before_action.

Upvotes: 0

smathy
smathy

Reputation: 27971

I'm not sure I've understood this, you're entering get "/a/path", to: "controller#action" and wondering why this is creating a GET route?

You're gonna kick yourself:

delete '/post_delete', to: 'posts#destroy'

But the real question here is why you're not using the delete route from your resources :posts? Then you'd just use:

button_to 'Delete', @post, method: :delete

Upvotes: 0

Related Questions