Проблема Rails 5 с belongs_to, когда модель ассоциации имеет пользовательское имя таблицы.ActiveRecord::Исключение InvalidForeignKey:PG::ForeignKeyViolation:

#ruby-on-rails #postgresql

#ruby-on-rails #postgresql

Вопрос:

В Rails 5 возникли проблемы с отношением belongs_to, когда модель ассоциации имеет пользовательское имя таблицы.

Ниже приведен пример

 class Department < ApplicationRecord
  self.table_name = 'custom_departments'
end
  
 class Request < ApplicationRecord
  belongs_to :department, class_name: 'Department', foreign_key: 'department_id', optional: true
end
  

Когда я пытаюсь сохранить объект запроса, он терпит неудачу и получает приведенную ниже ошибку

 request = Request.new(department_id: 1)
request.save

**ActiveRecord::InvalidForeignKey Exception:PG::ForeignKeyViolation:ERROR:insert or update on table "requests" violates foreign key constraint "fk_rails_8aaaf05eb8"
Key (department_id)=(1) is not present in table "departments".**
  

Спасибо

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

1. у вас уже есть отдел с ID = 1 в таблице custom_departments?

2. Да, у меня есть строка с идентификатором 1 в таблице custom_departments.

Ответ №1:

Внимательно посмотрите на сообщение об ошибке, которое вы получаете от PostgreSQL (не Rails):

 insert or update on table "requests" violates foreign key constraint
...
is not present in table "departments".*
  

У вас проблема с ограничением внешнего ключа, которое ссылается departments (не custom_departments ) внутри вашей базы данных PostgreSQL. Вы изначально создали departments таблицу и имели что-то вроде:

 t.references :department, foreign_key: true
  

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

Вам нужно удалить старый FK (и, возможно, departments таблицу) и добавить новый FK, который ссылается на нужную таблицу при миграции:

 def change
  remove_foreign_key :requests, :departments
  drop_table :departments # Assuming this is what you really want of course
  add_foreign_key :requests, :custom_departments, column: :department_id
end
  

Ответ №2:

Вы создаете запрос для несуществующего отдела. Вам нужно обратиться к существующему объекту.

 some_department = Department.all.first // get department you want to refer to 

request = Request.new 
request.department = some_department
request.save