class RuboCop::Cop::Rails::StrongParametersExpect
params.expect(user: [:name, :age])
# good
params.permit(user: [:name, :age]).require(:user)
params.require(:user).permit(:name, :age)
# bad
@example
strong parameter conventions.
incompatibility introduced for valid reasons by the ‘expect` method, which aligns better with
from 500 to 400 when handling invalid parameters. This change, however, reflects an intentional
This cop’s autocorrection is considered unsafe because there are cases where the HTTP status may change
@safety
Enforces the use of ‘ActionController::Parameters#expect` as a method for strong parameter handling.
def expect_method(require_method, permit_method)
def expect_method(require_method, permit_method) require_key = require_key(require_method) permit_args = permit_method.arguments.map(&:source).join(', ') arguments = "#{require_key}[#{permit_args}]" "expect(#{arguments})" end
def offense_range(method_node, node)
def offense_range(method_node, node) method_node.loc.selector.join(node.source_range.end) end
def on_send(node)
def on_send(node) return if part_of_ignored_node?(node) if (permit_method, require_method = params_require_permit(node)) range = offense_range(require_method, node) prefer = expect_method(require_method, permit_method) replace_argument = true elsif (require_method, permit_method = params_permit_require(node)) range = offense_range(permit_method, node) prefer = "expect(#{permit_method.arguments.map(&:source).join(', ')})" replace_argument = false else return end add_offense(range, message: format(MSG, prefer: prefer)) do |corrector| corrector.remove(require_method.receiver.source_range.end.join(require_method.source_range.end)) corrector.replace(permit_method.loc.selector, 'expect') if replace_argument corrector.insert_before(permit_method.first_argument, "#{require_key(require_method)}[") corrector.insert_after(permit_method.last_argument, ']') end end ignore_node(node) end
def require_key(require_method)
def require_key(require_method) if (first_argument = require_method.first_argument).respond_to?(:value) require_arg = first_argument.value separator = ': ' else require_arg = first_argument.source separator = ' => ' end "#{require_arg}#{separator}" end