Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot delete or update a parent row: a foreign key constraint fails - deleting a post in blog

I've checked out the other answers to similar questions and I think I understand what they are a saying but I'm at a loss to how to solve it.

I get this error message, when trying to delete a post in the blog on my site. I've tried from Rails console and get a similar message also.

ActiveRecord::StatementInvalid in PostsController#destroy
Mysql2::Error: Cannot delete or update a parent row: a foreign key constraint fails (`mysite_development`.`comments`, CONSTRAINT `fk_rails_2fd19c0db7` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`)): DELETE FROM `posts` WHERE `posts`.`id` = 3

posts_controller.rb

class PostsController < ApplicationController
  before_filter :authenticate, :except => [ :index, :show ]
  before_action :set_post, only: [:show, :edit, :update, :destroy]

  # GET /posts
  # GET /posts.json
  def index
    @posts = Post.all
  end

  # GET /posts/1
  # GET /posts/1.json
  def show
  end

  # GET /posts/new
  def new
    @post = Post.new
  end

  # GET /posts/1/edit
  def edit
  end

  # POST /posts
  # POST /posts.json
  def create
    @post = Post.new(post_params)

    respond_to do |format|
      if @post.save
        format.html { redirect_to @post, notice: 'Post was successfully created.' }
        format.json { render :show, status: :created, location: @post }
      else
        format.html { render :new }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /posts/1
  # PATCH/PUT /posts/1.json
  def update
    respond_to do |format|
      if @post.update(post_params)
        format.html { redirect_to @post, notice: 'Post was successfully updated.' }
        format.json { render :show, status: :ok, location: @post }
      else
        format.html { render :edit }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /posts/1
  # DELETE /posts/1.json
  def destroy
    @post.destroy
    respond_to do |format|
      format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
      format.json { head :no_content }

    end

  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_post
      @post = Post.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def post_params
      params.require(:post).permit(:title, :body)
    end
end

edit.html.erb

<h1>Editing Post</h1>

<%= render 'form' %>

<%= link_to 'Show', @post %> |
<%= link_to 'Back', posts_path %>
<%= link_to 'Delete', @post, method: :delete %>

_form.html.erb

<%= simple_form_for(@post) do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.input :title %>
    <%= f.input :body %>
  </div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

Any ideas?

like image 368
boogiewonder Avatar asked Mar 13 '23 22:03

boogiewonder


2 Answers

It has nothing to do with your controller code. You added a database foreign constraing in your schema that disallows you to delete an object when there are associated records.

In this case, you are trying to delete an Post that has Comments attached. You need to alter the schema and update the foreign key definition to instruct the database what to do in this case. Specifically, you may probably want to delete the associated records on cascade.

In theory, you can use the dependent: :destroy Rails setting in the Post model to delete the Comments on cascade, but it's not a good idea as you have a foreign key in place. It will be faster and better if you delegate the task to the database in this case.

like image 180
Simone Carletti Avatar answered May 05 '23 14:05

Simone Carletti


Try putting dependent: :destroy on the Model, which I imagine will be something like that. Luck.

class Post < ActiveRecord::Base
  has_many   :comments, dependent: :destroy
like image 45
sesperanto Avatar answered May 05 '23 13:05

sesperanto