# Request

  • Introduction

    Rails ActionDispatch::Request class provides an object-oriented way to interact with the current HTTP request being handled by your application and ActionController::StrongParameters provide access to data sent in by the user or other parameters in your controller actions

  • Interacting With The Request

    • Accessing The Request

      You can obtain an instance of the current HTTP request in your controller via request.

      @full_path = request.original_fullpath
      
      1

      | --- | --- |

  • Input

    You will probably want to access data sent in by the user or other parameters in your controller actions. There are two kinds of parameters possible in a web application. The first are parameters that are sent as part of the URL, called query string parameters. The query string is everything after "?" in the URL. The second type of parameter is usually referred to as POST data. This information usually comes from an HTML form which has been filled in by the user. It's called POST data because it can only be sent as part of an HTTP POST request. Rails does not make any distinction between query string parameters and POST parameters, and both are available in the [params](https://api.rubyonrails.org/v7.0.4/classes/ActionController/StrongParameters.html#method-i-params)hash in your controller:

    class ClientsController < ApplicationController
      # This action uses query string parameters because it gets run
      # by an HTTP GET request, but this does not make any difference
      # to how the parameters are accessed. The URL for
      # this action would look like this to list activated
      # clients: /clients?status=activated
      def index
        if params[:status] == "activated"
          @clients = Client.activated
        else
          @clients = Client.inactivated
        end
      end
    
      # This action uses POST parameters. They are most likely coming
      # from an HTML form that the user has submitted. The URL for
      # this RESTful request will be "/clients", and the data will be
      # sent as part of the request body.
      def create
        @client = Client.new(params[:client])
        if @client.save
          redirect_to @client
        else
          # This line overrides the default rendering behavior, which
          # would have been to render the "create" view.
          render "new"
        end
      end
    end
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    • Hash and Array Parameters

      The paramshash is not limited to one-dimensional keys and values. It can contain nested arrays and hashes. To send an array of values, append an empty pair of square brackets "[]" to the key name:

      GET /clients?ids[]=1&ids[]=2&ids[]=3
      
      1

      The value of params[:ids]will now be ["1", "2", "3"]. Note that parameter values are always strings; Rails does not attempt to guess or cast the type.

      To send a hash, you include the key name inside the brackets:

      <form accept-charset="UTF-8" action="/clients" method="post">
        <input type="text" name="client[name]" value="Acme" />
        <input type="text" name="client[phone]" value="12345" />
        <input type="text" name="client[address][postcode]" value="12345" />
        <input type="text" name="client[address][city]" value="Carrot City" />
      </form>
      
      1
      2
      3
      4
      5
      6
    • JSON Parameters

      If you're writing a web service application, you might find yourself more comfortable accepting parameters in JSON format. If the "Content-Type" header of your request is set to "application/json", Rails will automatically load your parameters into the params  hash, which you can access as you would normally.

      So for example, if you are sending this JSON content:

      { "company": { "name": "acme", "address": "123 Carrot Street" } }
      
      1

      Your controller will receive params[:company]as { "name" => "acme", "address" => "123 Carrot Street" } .

  • Input Filtering

    Action Controller parameters are forbidden to be used in Active Model mass assignments until they have been permitted.

    This means that you'll have to make a conscious decision about which attributes to permit for mass update. This is a better security practice to help prevent accidentally allowing users to update sensitive model attributes.

    params.permit(:id)
    
    
    1
    2

    permits the specified key (:id) for inclusion if it appears in paramsand it has a permitted scalar value associated. Otherwise, the key is going to be filtered out, so arrays, hashes, or any other objects cannot be injected.

    The permitted scalar types are StringSymbolNilClassNumericTrueClassFalseClassDateTimeDateTimeStringIOIOActionDispatch::Http::UploadedFile, and Rack::Test::UploadedFile.

    To declare that the value in paramsmust be an array of permitted scalar values, map the key to an empty array:

    params.permit(id: [])
    
    1

    Sometimes it is not possible or convenient to declare the valid keys of a hash parameter or its internal structure. Just map to an empty hash:

    params.permit(preferences: {})
    
    1

    but be careful because this opens the door to arbitrary input. In this case, permit  ensures values in the returned structure are permitted scalars and filters out anything else.

    To permit an entire hash of parameters, the [permit!](https://api.rubyonrails.org/v7.0.4/classes/ActionController/Parameters.html#method-i-permit-21) method can be used:

    
    params.require(:log_entry).permit!
    
    
    1
    2
    3

    # Nested Parameter

    You can also use permit on nested parameters, like:

    params.permit(:name, { emails: [] },
                  friends: [ :name,
                             { family: [ :name ], hobbies: [] }])
    
    1
    2
    3