#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