21

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.

0

2 Answers 2

50

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
Sign up to request clarification or add additional context in comments.

4 Comments

I haven't tested this, but that's clever. Thank you @tombeynon!
It's actually even possible to allow multiple types like so: params.permit(:attr, { :attr => [] }, { :attr => {} }). However, as much as I like this behaviour, I couldn't find it anywhere in the documentation... It works, though.
BRILLIANT! Would've never thought of that! :D
Still works in rails 7, however, in my case, order mattered and I had to put the scalar value before the array. Otherwise, a syntax error was thrown..
11

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

1 Comment

Oh snap, that's brilliant!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.