20
votes

Using Strong Parameters in my Rails Controller, how can I state that a permitted parameter can be a String or an Array?

My strong params:

class SiteSearchController < ApplicationController
    [...abbreviated for brevity...]

    private
    def search_params
        params.fetch(:search, {}).permit(:strings)
    end
end

I'm wanting to POST string(s) to search as a String or as an Array:

To search for 1 thing:

{
    "strings": "search for this"
}

OR, to search for multiple things:

{
    "strings": [
        "search for this",
        "and for this",
        "and search for this string too"
    ]
}

Update:

Purpose: I'm creating an API where my users can "batch" requests (getting responses via web-hooks), or make a one-off request (getting an immediate response) all on the same endpoint. This question is only 1 small part of my requirement.

The next piece will be doing this same logic, where I'll allow the search to happen on multiple pages, i.e.:

[
    {
        "page": "/section/look-at-this-page",
        "strings": "search for this"
    },
    {
        "page": "/this-page",
        "strings": [
            "search for this",
            "and for this",
            "and search for this string too"
        ]
    }
]

OR on a single page:

{
    "page": "/section/look-at-this-page",
    "strings": "search for this"
}

(which will make me need to have Strong Params allow an Object or an Array to be sent.

This seems like a basic thing, but I'm not seeing anything out there.

I know that I could just make the strings param an array, and then require searching for 1 thing to just have 1 value in the array... but I want to have this parameter be more robust than that.

2

2 Answers

40
votes

You can just permit the parameter twice - once for an array and once for a scalar value.

def search_params
    params.fetch(:search, {}).permit(:strings, strings: [])
end
10
votes

You could check if params[:strings] is an array and work from there

def strong_params
  if params[:string].is_a? Array
    params.fetch(:search, {}).permit(strings: [])
  else 
    params.fetch(:search, {}).permit(:strings)
  end
end