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