Class: RuboCop::Cop::DevDoc::Rails::StrongParametersExpect
- Inherits:
-
Base
- Object
- Base
- RuboCop::Cop::DevDoc::Rails::StrongParametersExpect
- Extended by:
- AutoCorrector
- Defined in:
- lib/rubocop/cop/dev_doc/rails/strong_parameters_expect.rb
Overview
Flag params.require(:foo).permit(...) and the reverse form
params.permit(foo: ...).require(:foo) — use params.expect(foo: [...])
instead.
Rationale
The upstream Rails/StrongParametersExpect autocorrects two distinct
patterns: the hash-form rewrite (require.permit → expect) and the
scalar form (params[:id] inside find-method chains). The scalar form
fires false positives on optional query params (e.g.
params[:status]&.to_sym || :draft) and forces scattered per-line
disables — the typical workaround is to disable the upstream cop
entirely, losing the hash-form benefit too.
This cop targets only the hash-form rewrite, so projects can keep
Rails/StrongParametersExpect: Enabled: false and still enforce the
safe params.expect pattern.
params.expect raises ActionController::ParameterMissing for scalar
values where permit would silently return nil, and it makes the
permitted-attribute shape explicit in one call.
Patterns detected
❌ require → permit chain
params.require(:user).permit(:name, :email)
❌ permit → require chain (less common)
params.permit(user: %i[name email]).require(:user)
✔️
params.expect(user: [:name, :email])
Not flagged
Scalar params[:foo] in any context — leave that to per-project
decision or the upstream cop.
Autocorrect is UNSAFE (SafeAutoCorrect: false)
expect is not a drop-in for require+permit; both deltas below were
verified against a production suite (81 test failures before manual
fix-ups):
- Empty-slice 400:
expectraises ParameterMissing when the key is present but every value filters out —permitreturned an empty slice and proceeded. Bites "slice-style" param methods that probe for whichever keys arrived (e.g. a publishing_params called unconditionally in update). Keep those tolerant withparams.fetch(:key, {}).permit(...)+ an inline reason. - Silent collection loss:
expectfilters with explicit_arrays, so collection-valued nested attributes (numeric-keyed fields_for / dynamic-group hashes,{"0"=>{...}}) require the double-array[[...]]declaration. The flat[...]this autocorrect emits SILENTLY filters such collections to empty — no error, no data. After correcting, audit every *_attributes key: has_many nests need[[...]], has_one nests stay flat.
The corrector also deliberately skips permit calls whose arguments
are computed (e.g. permit([...static...] + extra)): copying the
expression into expect(key: [<expr>]) would produce a one-element
outer array — which IS expect's array-of-hashes syntax, silently
changing semantics. Those sites are flagged without a correction.
Constant Summary collapse
- MSG_REQUIRE_PERMIT =
'Use `params.expect(%<key>s: [...])` instead of ' \ '`params.require(:%<key>s).permit(...)`.'.freeze
- MSG_PERMIT_REQUIRE =
'Use `params.expect(%<key>s: ...)` instead of ' \ '`params.permit(%<key>s: ...).require(:%<key>s)`.'.freeze
- RESTRICT_ON_SEND =
%i[permit require].freeze
Instance Method Summary collapse
Instance Method Details
#on_send(node) ⇒ Object
91 92 93 94 |
# File 'lib/rubocop/cop/dev_doc/rails/strong_parameters_expect.rb', line 91 def on_send(node) check_require_permit(node) if node.method_name == :permit check_permit_require(node) if node.method_name == :require end |