#ruby-on-rails #postgresql #foreign-keys
#ruby-on-rails #postgresql #внешние ключи
Вопрос:
Рассмотрим следующие связанные таблицы:
Некоторым exercises
«требуется» машина, некоторым нет. Я думаю, что machine
поле должно быть логическим.
Затем при сохранении session_set
, если логическое значение равно true
, я хочу потребовать, чтобы machine_id
внешний ключ был сохранен. Если false, то ключ foregin не требуется.
Возможно ли это вообще, или это опровергает общую цель наличия внешнего ключа?
Комментарии:
1. NOT NULL SQL FK — это список столбцов, подстроки которого отображаются в другом месте как PK или УНИКАЛЬНЫЕ. (Грубо говоря, реляционный внешний суперключей.) Вы не описываете ни NOT NULL, ни nullable SQL FK, потому что эти вещи не действуют так, как вы описываете. Таким образом, вам не следует использовать «FK» для обозначения вашего предложения. Это просто напоминает FK. Пара (логическое значение, ключ) в вашем проекте соответствует значению FK с нулевым значением (ключ или NULL) в SQL, где ваш тест целостности «B ИЛИ K находится в таблице ссылок» соответствует тесту целостности SQL «K РАВНО НУЛЮ ИЛИ K находится в таблице ссылок». PS Прочитайте ссылку и / или руководство, прежде чем задавать вопрос.
Ответ №1:
Внешний ключ может быть как обязательным, так и необязательным (он может содержать или не может содержать null), поэтому вам не нужно никакого дополнительного логического поля.
в rails 5 по умолчанию требуется belongs_to
ассоциация, поэтому мы указываем, что это optional
belongs_to :machine, optional: true
перед rails 5 должно быть достаточно
belongs_to :machine
Теперь вам нужно убедиться, что ваше поле в таблице базы данных не имеет null: false
ограничений и все настроено.
Теперь я заметил, что ваше поле вызывается machine
не machine_id
так, как rails хочет по умолчанию. В этом случае попробуйте
belongs_to :machine, optional: true, foreign_key: :machine
Комментарии:
1. Спасибо! У меня есть стандартный
belongs_to :machine
, и я добавлю вам дополнения и протестирую. Спасибо!2. сработало как по волшебству — хотя я опустил дополнительное обозначение внешнего ключа, поскольку оно уже существует в моей версии