auto
auto

Reputation: 1173

Rails Delete doesn't destroy record, simply refreshes

My destroy/delete link simply refreshes the post page and doesn't actually delete the record.

<span class="delete-button"><%= link_to 'Delete', post_path(@post), method: :delete, data: { confirm: 'Are you sure?' } %>
</span>

Controller

 def destroy
    @post= Post.find(params[:id])

    @post.destroy

    redirect_to posts_path

  end

Upvotes: 2

Views: 1896

Answers (3)

auto
auto

Reputation: 1173

The solution was to use button_to instead of link_to

That revealed additional error that required me to define the has_many association above/before the has_many :through associations in the Post model.

Unsure why link_to does not work in this case.

Upvotes: 3

Zoran
Zoran

Reputation: 4226

If your page is refreshing and not performing a redirect per the controller action, it's possible that the page doesn't have rails-ujs set up. Without it you can't make non-GET requests via hyperlinks, so the link would simply go to the post's show page.

If the record is truly failing to delete, it could be due to several reasons. One way to narrow down why the Post failed to delete would be to rescue out of the exception that destroy! raises and log or display the post's errors:

def destroy
  post = Post.find(params[:id])
  post.destroy!

  redirect_to posts_path, notice: "Post deleted successfully"
rescue ActiveRecord::RecordNotDestroyed => e
  failure_message = "Post failed to delete: #{e.record.errors.full_messages}"

  Rails.logger.warn "==> #{failure_message}"
  redirect_to posts_path, alert: failure_message
end

If you don't have flash messages set up for your view, you can place this in your view file:

<% flash.each do |_type, message| %>
  <div><%= message %></div>
<% end %>

Now if the post fails to delete you can display a flash message stating why it failed (or you can check your logs for a ==> Post failed to delete: ... line).

Upvotes: 1

Schwern
Schwern

Reputation: 165546

You are failing to check if @post.destroy succeeds, it returns true or false.

Simplest thing to do is to use @post.destroy! which will throw an exception if it fails. In general, use the ! versions to ensure you don't miss any errors: create!, destroy!, save!, and update!.

My guess is the @post has associated objects which refer to the Post. These must be deleted before Post is deleted. You can fix this by adding dependent: :destroy to its relationships.

class Comment
  belongs_to :post
end

class Post
  has_many :comments, dependent: :destroy
end

Upvotes: 1

Related Questions