Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invalid foreign key when deleting tags in rails

I am following this tutorial. The tutorial requires me to implement the destroy function for tags.

The tags can be created and shown fine. However, destroying them yields the following error:

 Parameters: {"authenticity_token"=>"VcYU8FRqn4oBXCv0NKXuO7yKNdI+9fIk46rY1ZwD7cQ8cqi37nZDVwNnWJLcNMWVq4gi3OU3YFDgzdeTRa1XKw==",
 "id"=>"1"}
  Tag Load (0.5ms)  SELECT  "tags".* FROM "tags" WHERE "tags"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
   (0.0ms)  begin transaction
  SQL (2.0ms)  DELETE FROM "tags" WHERE "tags"."id" = ?  [["id", 1]]
   (1.0ms)  rollback transaction
Completed 500 Internal Server Error in 10ms (ActiveRecord: 3.5ms)



ActiveRecord::InvalidForeignKey (SQLite3::ConstraintException: FOREIGN KEY constraint failed: DELETE FROM "tags" WHERE "tags"."i
d" = ?):

app/controllers/tags_controller.rb:13:in `destroy

tags_controller.rb

class TagsController < ApplicationController

    def index
        @tags = Tag.all
    end

    def show
        @tag = Tag.find(params[:id])
    end

    def destroy
        @tags = Tag.find(params[:id])
        @tags.destroy
        # Set variable to instance of an object of class Article and call .destroy on it.
    end
end

index.html.erb

<h1>Listing tags</h1>

  <% @tags.each do |tag| %>
    <tr>
      <td><%= tag.name %></td>
      <td><%= link_to 'Show', tag_path(tag) %></td>
      <td><%= link_to 'Delete', tag_path(tag),
              method: :delete,
              data: { confirm: 'Are you sure?' } %></td>
    </tr>
  <% end %>
</table>

Is there a step i missed out or something I entered wrong?

like image 330
Carrein Avatar asked Jan 03 '23 18:01

Carrein


1 Answers

You have a foreign key relationship between tag and some other entity in your application. If you deleted a tag, the records which rely on that tag would become orphaned, so the database prevents you from breaking referential integrity.

You can either get rid of that relationship (in your model file, you probably specified a has_manyrelationship that you can remove) or you can specify a dependent: :destroy clause which destroys all related records when you destroy the associated tag. The first option is less than desirable because you end up with a lot of rows with nulls which you then have to clean up later on. The second option is better because you preserve referential integrity (the relationship between tables in your database).

For example, your tag.rb file might look something like this:

class Tag < ApplicationRecord
  has_many :foos, dependent: :destroy
end

This way, when you delete a tag from the database, all associated foos are also destroyed, and the database won't complain. Read up on AR associations here.

like image 168
MarsAtomic Avatar answered Jan 13 '23 09:01

MarsAtomic