Practice · Reading the Source · Card 1
What does optional: true actually change?
One option flag separates these two models. The visible difference is "must have a user vs not." The mechanism behind it is more specific than that.
The code
Same association. Different behavior. What did Rails wire up differently?
class Post < ApplicationRecord
belongs_to :user
end
class Comment < ApplicationRecord
belongs_to :user, optional: true
end The question
A Post with no user can't save. A Comment with no user saves fine. Which of these is the actual mechanism behind that difference?
Take a moment. Pick the best answer. Wrong picks reveal why they're wrong, which is half the point.
✅ Answer breakdown
✗ A. It tells the database to allow NULL in the foreign key column.
Whether the column allows NULL is decided by the migration (null: false or not). belongs_to never modifies your schema.
✓ B. It skips installing the presence validation that belongs_to would normally add.
Rails 5+ belongs_to installs a presence validation by default. optional: true tells the builder to skip it. You can confirm with Post.validators_on(:user) vs Comment.validators_on(:user).
✗ C. It makes the association polymorphic so the comment can belong to anything.
Polymorphism comes from polymorphic: true, which is a separate option. optional: true doesn't change cardinality.
✗ D. It removes the helper methods like build_user and create_user.
The helper methods are generated regardless of optional. They come from the association itself, not from the validation.
💡 The principle
Whether belongs_to installs a presence validation by default is controlled by the global setting config.active_record.belongs_to_required_by_default. In Rails 5+, that's true for new apps. In apps upgraded from Rails 4, it's often still false. Two Rails apps can run the same belongs_to :user line and behave differently. The behavior isn't in the line; it's in the setting the line consults.
📚 Theory
For the full walkthrough, read Reading the Source · Card 1 — What belongs_to :user actually adds.