ОШИБКА: удаление по таблице нарушает ограничение внешнего ключа. Ключевой идентификатор по-прежнему ссылается на таблицу (многие)
Я работаю с Rails и PostgreSQL и имею базовое отношение один-ко-многим, один Auction
имеет много Bid
. Однако, когда я пытаюсь удалить аукцион (на котором есть ставки), я получаю следующую ошибку:
ОШИБКА: обновление или удаление в таблице "аукционы" нарушает ограничение внешнего ключа "fk_rails_43e9021cbf" для таблицы "ставки". ПОДРОБНО: На ключ (id) = (1) все еще ссылаются из таблицы "ставки".
Удаление аукционов без ставок не дает ошибок.
Меня смущает то, что внутри моей Auction
модели у меня есть:
has_many :bids, dependent: :destroy
![Error Screen Shot (better_error gem)]()
Так как у меня есть зависимое предложение уничтожения, почему я все еще получаю эту ошибку?
РЕДАКТИРОВАТЬ: я пытался удалить всю БД, а затем воссоздать/перенастроить все - все еще получаю ту же ошибку.
Ответы
Ответ 1
Моя проблема заключалась в том, что я использую @auction.delete
(видно на скриншоте, который я разместил) при попытке удалить запись.
Удалить будет игнорировать любые обратные вызовы, которые у меня есть на месте. Так что, хотя у меня есть зависимое предложение destroy, оно не вызывается - следовательно, Rails выдает ошибку. Если/когда я изменил код на read @auction.destroy
, @auction.destroy
обратный вызов, и это решило проблему.
Ссылка: Разница между Уничтожить и Удалить
Ответ 2
От Rails v4.2 вы можете сделать это:
Создайте миграцию для обновления внешних ключей
20160321165946_update_foreign_key.rb
class UpdateForeignKey < ActiveRecord::Migration
def change
# remove the old foreign_key
remove_foreign_key :posts, :users
# add the new foreign_key
add_foreign_key :posts, :users, on_delete: :cascade
end
end
Ответ 3
Используете ли вы delete
или destroy
для удаления объектов? Я думаю, вы используете delete
, и вы хотите использовать destroy
См. http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#module-ActiveRecord::Associations::ClassMethods-label-Delete+or+destroy-3F
Ответ 4
Вы случайно используете драгоценный камень паранойи или что-то подобное?
Если вы bids
являются paranoid
и auctions
нет, вы можете столкнуться с этой ошибкой.
Это произошло бы потому, что когда rails выполняет dependent: destroy
, он мягко удаляет заявки, но они все еще фактически существуют в БД (у них просто установлен столбец deleted_at
). Следовательно, ограничение внешнего ключа не будет выполнено.
Ответ 5
Ваша ошибка из базы данных, а не рельсы. Вам необходимо сначала удалить ставки в приложении или изменить ограничение внешнего ключа в db для каскадирования удаления
Ответ 6
Marc Busqué очень хорошая статья об этой проблеме, которая может помочь.
"Когда ActiveRecord обнаруживает нарушение внешнего ключа, он вызывает исключение ActiveRecord:: InvalidForeignKey. Даже если в его документации он просто говорит, что он возникает, когда запись не может быть вставлена или обновлена, поскольку она ссылается на несуществующую запись, дело в том, что оно также используется в интересующем нас случае".
С этим и rescue_from мы можем просто добавить к ApplicationController или к проблеме с контроллером:
rescue_from 'ActiveRecord::InvalidForeignKey' do
# Flash and render, render API json error... whatever
end