mohammad.hussain
Mon Jan 27 2025
The Rails 8.0 release introduces several new features, and among them, params#expect stands out.
In our daily work with Rails, we often rely on params#require for assignments and queries. However, params#require is more explicit than permit. Here’s an example to illustrate:
If you expect the posts parameter to contain a list of IDs, such as [{id: 1}, {id: 2}], you can define your expectations like this:
The output will be:
Now, consider a different scenario where you expect the posts parameter to have only a single hash with an ID, like this:
If you use:
It will raise the following error:
ActionController::ExpectedParameterMissing: param is missing or the value is empty or invalid: posts
In contrast, using the older params#permit:
Will not enforce your expectation of the nested parameter structure and will accept it without validation.
In our daily work with Rails, we often rely on params#require for assignments and queries. However, params#require is more explicit than permit. Here’s an example to illustrate:
params = ActionController::Parameters.new(posts: [{id: 1}])
If you expect the posts parameter to contain a list of IDs, such as [{id: 1}, {id: 2}], you can define your expectations like this:
params.expect(posts: [[:id]])
The output will be:
[
#<ActionController::Parameters {"id"=>1} permitted: true>,
#<ActionController::Parameters {"id"=>2} permitted: true>
]
Now, consider a different scenario where you expect the posts parameter to have only a single hash with an ID, like this:
params = ActionController::Parameters.new(posts: {id: 1})
If you use:
params.expect(posts: [[:id]])
It will raise the following error:
ActionController::ExpectedParameterMissing: param is missing or the value is empty or invalid: posts
In contrast, using the older params#permit:
params.permit(posts: [:id])
Will not enforce your expectation of the nested parameter structure and will accept it without validation.