Подтвердить что ты не робот

ОШИБКА: удаление по таблице нарушает ограничение внешнего ключа. Ключевой идентификатор по-прежнему ссылается на таблицу (многие)

Я работаю с Rails и PostgreSQL и имею базовое отношение один-ко-многим, один Auction имеет много Bid. Однако, когда я пытаюсь удалить аукцион (на котором есть ставки), я получаю следующую ошибку:

ОШИБКА: обновление или удаление в таблице "аукционы" нарушает ограничение внешнего ключа "fk_rails_43e9021cbf" для таблицы "ставки". ПОДРОБНО: На ключ (id) = (1) все еще ссылаются из таблицы "ставки".

Удаление аукционов без ставок не дает ошибок.

Меня смущает то, что внутри моей Auction модели у меня есть:

has_many :bids, dependent: :destroy

Error Screen Shot (better_error gem)

Так как у меня есть зависимое предложение уничтожения, почему я все еще получаю эту ошибку?

РЕДАКТИРОВАТЬ: я пытался удалить всю БД, а затем воссоздать/перенастроить все - все еще получаю ту же ошибку.

4b9b3361

Ответ 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

Ответ 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