Я создал ассоциацию в rails для автора(has_many) и книги(belongs_to), Теперь при удалении автора(зависит: :уничтожить) я получаю выполнение

#ruby-on-rails #ruby

Вопрос:

2.7.2 :004 > Автор.найти(1).удалить загрузку автора (0,2 мс) ВЫБЕРИТЕ «авторы».* ОТ «авторы», ГДЕ «авторы».»идентификатор» = ? ПРЕДЕЛ ? [[«идентификатор», 1], [«ОГРАНИЧЕНИЕ», 1]] Уничтожение автора (1,0 мс) УДАЛЕНИЕ ИЗ «авторов», ГДЕ «авторы».»идентификатор» = ? [[«идентификатор», 1]] Обратная трассировка (последний последний вызов): ActiveRecord::InvalidForeignKey (SQLite3::Исключение ограничений: Ошибка ограничения ВНЕШНЕГО КЛЮЧА: УДАЛИТЬ ИЗ «авторов», ГДЕ «авторы».»идентификатор» = ?)

Это исключение, которое я получаю, когда выполняю удаление.

Моя авторская модель Выглядит так, также используется nullify

 class Author < ApplicationRecord
  has_many :books, dependent: :destroy
end
 

Моя книжная модель выглядит так

 class Book < ApplicationRecord
  belongs_to :author
end
 

Я могу уничтожить автора, и запись будет удалена, а также уничтожить книги с этим идентификатором автора, теперь я хочу просто удалить автора и хочу, чтобы книги остались там или были аннулированы, но при их удалении возникает исключение

Схема

 create_table 'authors', force: :cascade do |t|
    t.string 'name'
    t.integer 'age'
    t.datetime 'created_at', null: false
    t.datetime 'updated_at', null: false
  end

  create_table 'books', force: :cascade do |t|
    t.string 'name'
    t.integer 'price'
    t.integer 'author_id'
    t.datetime 'created_at', null: false
    t.datetime 'updated_at', null: false
    t.index ['author_id'], name: 'index_books_on_author_id'
 

ActiveRecord::InvalidForeignKey (исключение SQLite3::ConstraintException: Сбой ограничения ВНЕШНЕГО КЛЮЧА: УДАЛИТЬ ИЗ «авторов», ГДЕ «авторы».»идентификатор» = ?)

Комментарии:

1. Можете ли вы опубликовать модель книги, это очень полезно, чтобы помочь вам 🙂

2. ограничение связано с вашей миграцией; оно создало индекс в базе данных. вы также должны опубликовать сгенерированную схему. Кроме того, изучите форматирование вашего кода и вставок 🙂

Ответ №1:

Если вы хотите иметь возможность аннулировать author_id, вам необходимо создать миграцию, чтобы удалить внешний ключ и запустить его:

 class RemoveAuthorForeignKeyFromBooks < ActiveRecord::Migration[6.0]
  def change
    remove_foreign_key :books, :authors
  end
end
 

remove_foreign_key не работал должным образом на SQLite до Rails 6, поэтому вам может потребоваться обходной путь в более старых версиях.

 class Book < ApplicationRecord
  belongs_to :author, optional: true
end

class Author < ApplicationRecord
  has_many :books, dependent: :nullify
end
 

Если вы не выберете параметр отношения «принадлежит», вы не сможете обновить книгу после аннулирования идентификатора автора.