I understand that calling params.permit(:foo) creates a new ActionController::Parameters instance with :foo whitelisted so that you can instantiate a model with it. But why does the following code in the Discourse CMS call it without using its return value?
discourse/app/controllers/drafts_controller.rb: Github
class DraftsController < ApplicationController
# [...]
def index
# [...]
params.permit(:offset)
params.permit(:limit)
# [...]
opts = {
# [...]
offset: params[:offset],
limit: params[:limit]
}
stream = Draft.stream(opts)
This does look confusing, I agree.
Judging from the implementation of
#permitand the documentation ofActionController::Params, this can behave differently depending on the configaction_on_unpermitted_parameters, which accepts:logand:raiseas values and isnilby default.When
action_on_unpermitted_parameters = nil:Calling
params.permit(:foo)will return a newActionController::Parametersinstance marked as permitted with just that key.If you're not using the return value, this call makes little sense as there's no side effect. The receiver is not mutated.
When
action_on_unpermitted_parameters = :log:This behaves the same as above, but has the side effect of logging all not permitted keys:
As you can see, for each
permitcall, you'd get different logs. Thus, this would only make sense if the code in that controller would include all permitted (and required) parameters:When
action_on_unpermitted_parameters = :raise:The effect here is that it raises when the params contain keys that are not allowed. Similar to
:log, this also only would make sense when all permitted (and required) keys are specified:Contrast that to including all keys:
Having said that, I couldn't find any occurrence of
action_on_unpermitted_parametersin Discourse's codebase. Thus, the value isniland therefore I conclude that#permitin that controller action has no effect in terms of functionality.It could be there as a convention serving as documentation where first all required parameters are listed and then all optional ones.
Digging deeper, these
#permitcalls were introduced in this commit when it was still a separate gem called strong_parameters. The behavior of#permitin that gem was the same as today. This makes me think that the author of that commit misunderstood the API of strong_parameters.