Add nullable foreign key in Rails

Ruby on-RailsRubyRuby on-Rails-4Rails ActiverecordRuby on-Rails-4.2

Ruby on-Rails Problem Overview


Referencing to Rails 4.2 add_foreign_key support:

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

How to create a nullable foreign key constraint, to allow the situation, where articles.author_id can be sometimes null?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

Note that in Rails 5 and in Rails 6 you may need to mark the corresponding association as optional if it's 1:n (belongs_to), as the default was changed:

belongs_to :author, optional: true

This is the corresponding Changeset.

To use the old behavior across your application, you can also set:

Rails.application.config.active_record.belongs_to_required_by_default = false

in config/initializers/new_framework_defaults.rb

The error you will usually see is:

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'

You may also need to update any migration: change null: false to true and run rake db:redo if it had already run.

Solution 2 - Ruby on-Rails

Adding optional: true along with belongs_to :author in article model will do the job.

Solution 3 - Ruby on-Rails

There is nothing in the guide that implies add_foreign_key would make the corresponding foreign field "NOT NULL" or required. add_foreign_key simply adds a foreign key constraint whether the field is required or not (in your case author_id in articles).

Did you get an error when you tried this in your migration?

Here's the SQL that it would generate:

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

SO, if in your original migration of articles, author_id is null, then you can have foreign key that's nullable.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmaicherView Question on Stackoverflow
Solution 1 - Ruby on-RailsMatthias WinkelmannView Answer on Stackoverflow
Solution 2 - Ruby on-RailsRajan Verma - AarvyView Answer on Stackoverflow
Solution 3 - Ruby on-Railsuser1322092View Answer on Stackoverflow