ddonche
ddonche

Reputation: 1065

Deleting Record violates foreign key constraint

I have a table for notifications, which stores the ID from several Models, so a user gets a notification upon actions related to those (someone posted a comment on your article). The notifications do not "belong to" anything but a user it's going to, though, it's just referencing the IDs of things. So now whenever I try to delete an article, for example, I get an error:

ActiveRecord::InvalidForeignKey (PG::ForeignKeyViolation: ERROR:  update or delete on table "comments" violates foreign key constraint "fk_rails_9268535f02" on table "notifications"

How can I set it up to delete any referenced notifications also?

My db schema for notifications:

create_table "notifications", force: :cascade do |t|
t.integer  "recipient_id"
t.integer  "notified_by_id"
t.integer  "glip_id"
t.integer  "article_id"
t.integer  "group_id"
t.integer  "post_id"
t.integer  "comment_id"
t.integer  "notation_id"
t.integer  "response_id"
t.integer  "remark_id"
t.integer  "conversation_id"
t.integer  "message_id"
t.boolean  "read",              default: false
t.datetime "created_at",                        null: false
t.datetime "updated_at",                        null: false
t.integer  "notification_type"
t.index ["article_id"], name: "index_notifications_on_article_id"
t.index ["comment_id"], name: "index_notifications_on_comment_id"
t.index ["conversation_id"], name: "index_notifications_on_conversation_id"
t.index ["glip_id"], name: "index_notifications_on_glip_id"
t.index ["group_id"], name: "index_notifications_on_group_id"
t.index ["message_id"], name: "index_notifications_on_message_id"
t.index ["notation_id"], name: "index_notifications_on_notation_id"
t.index ["notified_by_id"], name: "index_notifications_on_notified_by_id"
t.index ["post_id"], name: "index_notifications_on_post_id"
t.index ["recipient_id"], name: "index_notifications_on_recipient_id"
t.index ["remark_id"], name: "index_notifications_on_remark_id"
t.index ["response_id"], name: "index_notifications_on_response_id"

end

And my notifications Model:

class Notification < ApplicationRecord
  enum notification_type: { comment: 0, notation: 1, message: 2, feature: 3, marked_helpful: 4,
                            participation: 5, response: 6, remark: 7, follow: 8, unfollow: 9 }
  enum read: { read: true, unread: false }
  belongs_to :notified_by, class_name: 'User'
end

Upvotes: 1

Views: 949

Answers (2)

Anand
Anand

Reputation: 6531

It may be due to while an article is deleted the associated comments are being deleted together and there is a foreign key constraint between comments and notifications tables at db level which prevents it from deletion.

My suggestion is to add dependent: :destroy in Comment model if you want that associated notifications to be deleted along with comments

class Comment < ApplicationRecord
  has_many :notifications, dependent: destroy
end

If you want to notifications not to be deleted while deleting comments

class Comment < ApplicationRecord
  has_many :notifications, dependent: :nullify
end

For more details please have a look Difference between dependet :destroy & dependent: :nullify

Upvotes: 2

Oleksii Filonenko
Oleksii Filonenko

Reputation: 1653

Your User should use the :dependent option:

class User < ApplicationRecord
  # ...
  has_many :notifications, foreign_key: :notified_by_id, dependent: :destroy
end

The :foreign_key should also be specified if you used :class_name on the belongs_to side of the association.

Now, when you delete a User, all of the notifications referencing them are also deleted.

You can repeat the same process for the Article or any other model referenced.

Upvotes: 2

Related Questions