2

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

Tomax47
  • 31
  • 2
  • It's bad idea to use GET to delete resources – mechnicov Aug 29 '23 at 20:39
  • Thanks for the feedback!! I changed the "get" to "delete", yet it ain't help, but showed an error in the destroy method. as I understood, it's caused by the relationships between the models I have, so I tried to clear the comments and the likes off the post before calling the destroy method on it, though that caused another nullViolation error at the ```@post.comments.clear``` part for the post_id. Have u got any ideas on how I cant clear the post from likes and comments so I could delete it? – Tomax47 Aug 29 '23 at 20:51
  • You also don't need custom `delete'/delete_post', too: 'posts#destroy'` because you have `resources` with `destroy` action – mechnicov Aug 29 '23 at 21:50
  • You don't need explicitly "clear" related entities, instead of this use `:dependent` option for `has_many` or database layer with `ON DELETE CASCADE` – mechnicov Aug 29 '23 at 21:50

2 Answers2

0

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
smathy
  • 26,283
  • 5
  • 48
  • 68
  • Well, Im new to rails, so thought that it's fine to use get for the post delete, as I alrdy used it for the user sign_out to destroy a session so thanks for mentioning it! I tried changing it to delete, using the delete route from the ```resources :posts``` tho it ain't work. but instead started showing the following error : ```undefined method `destroy' for [#]:Array``` – Tomax47 Aug 29 '23 at 19:46
  • 1
    it's trying to call `destroy` on an array. It's b/c you have `@post = current_user.posts.find([params[:id]])` in the destroy method of your controller... it should be `@post = current_user.posts.find(params[:id])`. Look carefully at the difference. Remove the square brackets `[]`. – Les Nightingill Aug 29 '23 at 21:56
  • Wow, good eyes @LesNightingill - I thought you'd gone batty for a second there :) – smathy Aug 30 '23 at 00:25
0

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.