48

How do I pass array of parameters through Get method in rails? Currently my URL loocs like this:

http://localhost:3000/jobs/1017/editing_job_suites/1017/editing_member_jobs/new?ids[]=1025&ids[]=1027

How can I pass the array with Get method but avoid ?ids[]=1025&ids[]=1027 part.

Request is being sent with javascript window.open method. Is there any workaround to send not ajax Post request.

DGM
  • 26,629
  • 7
  • 58
  • 79
Rafael Sedrakyan
  • 2,541
  • 10
  • 34
  • 42

4 Answers4

129

You should stick to using a GET request if you are not changing the state of anything, and all you want to to access a read only value.

To send an array of ids to rails in a GET request simply name your variable with square brackets at the end.

//angular snippet

$http.(method:'GET',
  ...
  params: {'channel_id':2, 'product_ids[]': productIds}  
  //where productIds is an array of integers
  ...
)

Do not concatenate your ids as a comma separated list, just pass them individually redundantly. So in the url it would look something like this:

?channel_id=2&product_ids[]=6900&product_ids[]=6901

url encoded it will actually be more like this:

?channel_id=2&product_ids%5B%5D=6900&product_ids%5B%5D=6901

Rails will separate this back out for you.

Parameters: {"channel_id"=>"2", "product_ids"=>["6900", "6901"]}
Homan
  • 25,618
  • 22
  • 70
  • 107
  • 7
    +1 for passing list of parameters using the "product_ids[]=6900&product_ids[]=6901" method – Lakota Lefler May 20 '14 at 17:07
  • 1
    The accepted answer is not helpful for people finding this page via web search, while this one is, so I am up-voting. However we should also note that the accepted answer is the one that more specifically answers to the question, since the OP stated that he already knew about the square bracket syntax. – mastazi Jan 08 '16 at 02:30
  • I'm using Rails 5 and the square brackets on the end of the variable names do not seem to make a difference. If you do not include them, it still works. One could probably argue that it is more clear that you are passing an array...for me, the fact that its plural is good enough. – Greg Blass Dec 08 '16 at 21:45
  • Almost there. If you do like this, then the request looks like this: `product_ids[][]=6900&product_ids[][]=6901`. To make it generate the correct URL, do like this: `params: {'channel_id':2, 'product_ids': productIds}`. Then it will generate the URL: `product_ids[]=6900&product_ids[]=6901`. – Maris Mar 22 '19 at 11:13
  • this converts array of integers into array of strings. any way around this? – Pants Aug 10 '22 at 17:01
25

No, GET can only put variables on the url itself. If you want the URL to be shorter, you have to POST. That's a limitation feature of HTTP, not Rails.

DGM
  • 26,629
  • 7
  • 58
  • 79
  • Or find another way of filtering it without using huge arrays. – YuriAlbuquerque Jul 03 '12 at 14:54
  • actually, the HTTP spec doesn't specifically state whether `GET` requests can have a body or not. This is the convention followed by web servers. If someone were to extend a web server to read the HTTP body for GET, then you could pass in a body with GET requests too. (Given you find/modify a client to pass a body with a GET request). – kapad Sep 01 '18 at 13:00
14

I recently wanted to do this and found a workaround that is a little less complex, and so has some complexity limitations but may also be easier to implement. Can't speak to security, etc.

If you pass your array values as a string with a delimiter, e.g.

http://example.com/controller?job_ids=2342,2354,25245

Then you can take the result and parse it back to what you want:

job_ids = params[:job_ids].split(',')

Then do whatever:

    job_ids.each do |job_id|
      job = Job.find(job_id.to_i)
    end

etc

Jason Preston
  • 1,343
  • 1
  • 10
  • 12
0

@Homan answer is valid for using an external client (e.g curl or angular). Inside Rails test cases though, you should not use []. Here's an example:

get get_test_cases_url(**path_params), params: {case_ids: ["NON-9450", "NON-12345", "NON-9361"]}

This is using new format where get_test_cases is name of route and you pass to the method all params needed to construct the URL path. Query params are a separate hash.

FYI if I use [] like case_ids[], then instead of ["NON-9450", "NON-12345", "NON-9361"] I'm getting it parsed to [["NON-9450"], ["NON-12345"], ["NON-9361"]]

akostadinov
  • 17,364
  • 6
  • 77
  • 85