This blog is part of our Rails 5 series.

In Rails 5, whenever we define a belongs_to association, it is required to have the associated record present by default after this change.

It triggers validation error if associated record is not present.

class User < ApplicationRecord
end

class Post < ApplicationRecord
  belongs_to :user
end

post = Post.create(title: 'Hi')
=> <Post id: nil, title: "Hi", user_id: nil, created_at: nil, updated_at: nil>

post.errors.full_messages.to_sentence
=> "User must exist"

As we can see, we can’t create any post record without having an associated user record.

How to achieve this behavior before Rails 5

In Rails 4.x world To add validation on belongs_to association, we need to add option required: true .

class User < ApplicationRecord
end

class Post < ApplicationRecord
  belongs_to :user, required: true
end

post = Post.create(title: 'Hi')
=> <Post id: nil, title: "Hi", user_id: nil, created_at: nil, updated_at: nil>

post.errors.full_messages.to_sentence
=> "User must exist"

By default, required option is set to false.

Opting out of this default behavior in Rails 5

We can pass optional: true to the belongs_to association which would remove this validation check.

class Post < ApplicationRecord
  belongs_to :user, optional: true
end

post = Post.create(title: 'Hi')
=> <Post id: 2, title: "Hi", user_id: nil>

But, what if we do not need this behavior anywhere in our entire application and not just a single model?

Opting out of this default behavior for the entire application

New Rails 5 applications come with an initializer named active_record_belongs_to_required_by_default.rb.

Rails.application.config.active_record.belongs_to_required_by_default = true

For new Rails 5 application the value is set to true.

We can turn off this default behavior by changing the value to false.

Rails.application.config.active_record.belongs_to_required_by_default = false

class Post < ApplicationRecord
  belongs_to :user
end

post = Post.create(title: 'Hi')
=> <Post id: 3, title: "Hi", user_id: nil, created_at: "2016-02-11 12:36:05", updated_at: "2016-02-11 12:36:05">

How older applications will work with this change?

The initializer configuration will be present only in newly generated Rails 5 apps. If you are upgrading from an older version of Rails, you can add this initializer yourself to enable this change for the entire application.