0

In my view file I implemented AJAX that makes a idempotent GET request to the following rendered URL:

resources_path(:param1 => "value1", :param2 => "value2", :param3 => "value3", :paramN => "valueN")

When I access the view page I get the error ActionController::UnfilteredParameters in Resources#index, which comes from Strong Parameters.

I think that the solution is to permit the above params in the ResourcesController below but how should I make this for the index action since the index action usually do not requires parameters (unlike e.g. create or update)? There is a best practice for this?


The controller is the following:

class ResourcesController < ApplicationController
  def index
    respond_to do |format|
      format.html
      format.js
    end
  end
end
Backo
  • 18,291
  • 27
  • 103
  • 170
  • Show us the controller action that causes the bug and the full stacktrace. – mrzasa Jan 08 '19 at 13:57
  • @mrzasa I updated the question. The error comes from [Strong Parameters](https://edgeguides.rubyonrails.org/action_controller_overview.html#strong-parameters) – Backo Jan 08 '19 at 14:01
  • Possible duplicate of [how to permit an array with strong parameters](https://stackoverflow.com/questions/16549382/how-to-permit-an-array-with-strong-parameters) – Mirv - Matt Jan 08 '19 at 14:18
  • 1
    @Mirv thats not in any way a valid duplicate. – max Jan 08 '19 at 14:21
  • The direct answer to your first part of question is a duplicate asked many times. I do agree with Max that most likely you aren't using the rails way for this stuff. Theoretically you might be trying to make an Single Page Application (spa) & look up a tutorial on that ... – Mirv - Matt Jan 08 '19 at 14:22
  • @max ... you did read the title? `"How should I permit parameters in index, edit and show actions?"` – Mirv - Matt Jan 08 '19 at 15:02

1 Answers1

2

You can whitelist parameters for any action in exactly the same way:

Foo.new( params.require(:foo).permit(:bar) )
# or for a flat hash
Foo.new( params.permit(:foo, :bar) )

The params hash is just a hash like object which has a permitted flag. Calling .permit returns a new ActionController::Parameters instance containing only the permitted keys and with the permitted flag set to true.

But this is the wrong answer to the wrong question.

This issue at hand is not whitelisting parameters in the index, edit and show parameters - rather the problem is that your application is using the parameters to create / update models from a GET request in the first place.

The routes for index, edit and show actions all correspond to GET requests which should be idempotent (they should not alter resources at all). This is especially important since they are saved in the browsers history which can lead to unexpected consequences if the user presses the back button.

           Prefix Verb   URI Pattern                                                                              Controller#Action
           things GET    /things(.:format)                                                                        things#index
                  POST   /things(.:format)                                                                        things#create
        new_thing GET    /things/new(.:format)                                                                    things#new
       edit_thing GET    /things/:id/edit(.:format)                                                               things#edit
            thing GET    /things/:id(.:format)                                                                    things#show
                  PATCH  /things/:id(.:format)                                                                    things#update
                  PUT    /things/:id(.:format)                                                                    things#update
                  DELETE /things/:id(.:format)                                                                    things#destroy

While GET methods can take parameters they should generally not be doing any mass assignment to a model.

Only the create and update action which correspond to the non-idempotent POST and PUT|PATCH methods should be concerned with param whitelisting. You should ensure that your ajax call is being sent to the correct path and uses the correct HTTP method.

max
  • 96,212
  • 14
  • 104
  • 165
  • Thanks for your answer. I know how to whitelist parameters for actions. My question is more related to how to state methods within a controller for idempotent requests e.g. in the `ResourcesController#index`. For example, in the create action you'd state `Resource.new(params.permit(:param1))`. There is a best practice or something similar? – Backo Jan 08 '19 at 16:58
  • A best practice is to avoid state if possible in idempotent requests - well basically because its not idempotent and will cause issues with caching. I think this is very much a [X & Y problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) and you should try asking about how to solve the original problem and not how to fix a broken solution. – max Jan 08 '19 at 17:35
  • Thanks for your comment that helps me to learn new things. Perhaps I should not use the AJAX in the way I'm doing. BTW I'm using it to faster the page loading by rendering the content from another controller. Hence the rendered URL. – Backo Jan 09 '19 at 02:38
  • @max do you mind explaining a bit more on why `GET` should not be concerned with param whitelisting? – smilence May 23 '20 at 00:31