We write about Ruby on Rails, React.js, React Native, remote work, open source, engineering and design.
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.
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
.
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?
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
.
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">