Добавить обнуляемый внешний ключ в Rails

Ссылка на поддержку add_foreign_key в Rails 4.2:

    # add a foreign key to `articles.author_id` referencing `authors.id`
    add_foreign_key :articles, :authors

Как создать обнуляемое ограничение внешнего ключа, чтобы разрешить ситуацию, когда articles.author_id иногда может быть нулевым?


person maicher    schedule 21.12.2014    source источник


Ответы (3)


В руководстве нет ничего, что предполагало бы, что add_foreign_key сделает соответствующее внешнее поле «НЕ NULL» или обязательным. add_foreign_key просто добавляет ограничение внешнего ключа независимо от того, является ли поле обязательным или нет (в вашем случае author_id в articles).

Вы получили сообщение об ошибке, когда попробовали это в своей миграции?

Вот SQL, который он сгенерирует:

ALTER TABLE "articles" ADD CONSTRAINT articles_author_id_fk FOREIGN KEY ("author_id") REFERENCES "authors" ("id")

ТАК, если в вашей исходной миграции articles author_id имеет значение null, тогда вы можете иметь внешний ключ, который может быть равен нулю.

person user1322092    schedule 21.12.2014
comment
Я считаю, что это верно для Rails 4 и ниже, верно? - person karns; 04.08.2020

Обратите внимание, что в Rails 5 и в Rails 6 вам может потребоваться пометить соответствующую ассоциацию как необязательную, если она равна 1:n (belongs_to), так как значение по умолчанию было изменено:

belongs_to :author, optional: true

Это соответствующий набор изменений.

Чтобы использовать старое поведение в вашем приложении, вы также можете установить:

Rails.application.config.active_record.belongs_to_required_by_default = false

in config/initializers/new_framework_defaults.rb

Обычно вы видите следующую ошибку:

ActiveRecord::RecordInvalid: Validation failed: Class must exist
    from /usr/local/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/validations.rb:78:in `raise_validation_error'

Вам также может понадобиться обновить любую миграцию: измените null: false на true и запустите rake db:redo, если она уже выполнялась.

person Matthias Winkelmann    schedule 14.06.2016

Добавление optional: true вместе с belongs_to :author в модель article сделает эту работу.

person Rajan Verma - Aarvy    schedule 23.01.2018
comment
Это работает только для mongoid... просто столкнулся с той же проблемой, но с использованием pg. Не работает, к сожалению. - person Boenne; 26.04.2020
comment
Приведенная выше строка взята непосредственно из моего приложения, работающего на PG. Я не сталкивался с такой проблемой при работе с Postgres. - person Rajan Verma - Aarvy; 19.10.2020