Practice · Reading the Source · Card 3
require vs []: what's the failure mode?
Two ways to reach into params for the same data. When the form submits without the expected key, they fail differently. The difference matters.
The code
A POST comes in with no post key in the body.
# Version 1:
params.require(:post).permit(:title, :body)
# Version 2:
params[:post].permit(:title, :body) The question
Both versions fail when the post key is missing. Which pair of errors do they raise?
Take a moment. Pick the best answer. Wrong picks reveal why they're wrong, which is half the point.
✅ Answer breakdown
✗ A. Both raise ActionController::ParameterMissing.
Only require raises that specific error. The bracket version doesn't know the key was supposed to be there.
✓ B. Version 1 raises ActionController::ParameterMissing (400). Version 2 raises NoMethodError on nil (500).
require(:post) asserts the key exists and tells Rails to render a 400 Bad Request automatically. params[:post] returns nil, and calling .permit on nil hits NoMethodError, which Rails surfaces as a 500.
✗ C. Version 1 returns an empty Parameters object. Version 2 raises NoMethodError.
require never returns silently for a missing key. That's its whole job.
✗ D. Both raise NoMethodError.
require raises its own specific error before any chained method would have the chance to fail.
💡 The principle
A missing form key is a client problem (they sent bad input), not a server crash. It should be a 400, not a 500. require turns the failure into a 400 with a clear message that names the missing key. The bracket version produces a 500 that wakes someone up at 2 AM and tells them their controller has a NoMethodError on nil.
Use require. It's the Rails idiom for a reason.
📚 Theory
For the full walkthrough, read Reading the Source · Card 5 — How params works (and what permit does).