Rails 5 makes belongs_to association required by default

Abhishek Jain

By Abhishek Jain

on February 15, 2016

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.

1
2class User < ApplicationRecord
3end
4
5class Post < ApplicationRecord
6  belongs_to :user
7end
8
9post = Post.create(title: 'Hi')
10=> <Post id: nil, title: "Hi", user_id: nil, created_at: nil, updated_at: nil>
11
12post.errors.full_messages.to_sentence
13=> "User must exist"
14

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 .

1
2class User < ApplicationRecord
3end
4
5class Post < ApplicationRecord
6  belongs_to :user, required: true
7end
8
9post = Post.create(title: 'Hi')
10=> <Post id: nil, title: "Hi", user_id: nil, created_at: nil, updated_at: nil>
11
12post.errors.full_messages.to_sentence
13=> "User must exist"
14

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.

1
2class Post < ApplicationRecord
3  belongs_to :user, optional: true
4end
5
6post = Post.create(title: 'Hi')
7=> <Post id: 2, title: "Hi", user_id: nil>
8

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 application comes with an initializer named new_framework_defaults.rb.

When upgrading from older version of Rails to Rails 5, we can add this initializer by running bin/rails app:update task.

This initializer has config named Rails.application.config.active_record.belongs_to_required_by_default = true

For new Rails 5 application the value is set to true but for old applications, this is set to false by default.

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

1
2Rails.application.config.active_record.belongs_to_required_by_default = false
3
4class Post < ApplicationRecord
5  belongs_to :user
6end
7
8post = Post.create(title: 'Hi')
9=> <Post id: 3, title: "Hi", user_id: nil, created_at: "2016-02-11 12:36:05", updated_at: "2016-02-11 12:36:05">
10

If you liked this blog, you might also like the other blogs we have written. Check out the full archive.

Stay up to date with our blogs. Sign up for our newsletter.

We write about Ruby on Rails, React.js, React Native, remote work,open source, engineering & design.