Pregunta

I'm posting a long nested list that looks like this image on firebug:

long nested list http://i.imm.io/1m4s2.jpeg

While you can see in the same image that the post is successful, the only thing that appears on the log is the following lines:

[2013-12-11 20:50:37] ERROR SystemStackError: stack level too deep /home/fotanus/.rvm/gems/ruby-2.0.0-p247/gems/rack-1.5.2/lib/rack/utils.rb:527

And no action seems to be executed on Rails.

The long list is being sent with the following line:

$.ajax({ type: "POST", url: '/projects', data: JSON.stringify({ sortd_items: sorted_items }) })

where sorted_items is printed in the image, generated by a recursive function.

Why this is happening, and how can I make things work as expected?

Edit: Using a smaller list seems to work:

Started POST "/projects" for 127.0.0.1 at 2013-12-11 21:01:08 -0200 Processing by ProjectsController#create as */* Parameters: {"{\"sortd_items\":"=>{"\"2\","=>{"\"5\","=>[{",\"6\","=>[{",\"7\","=>[{",\"8\","=>[{",\"3\","=>{"\"10\","=>[{",\"10\","=>[{",\"4\","=>[{",\"5\","=>[{",\"6\","=>[{",\"7\","=>[{",\"8\","=>[{",\"3\","=>{"\"10\","=>[{",\"10\","=>[{",\"4\","=>[{",\"9\","=>{"\"11\","=>[{",\"12\","=>{"\"13\","=>[{",\"14\","=>[{",\"15\","=>[{",\"13\","=>[{",\"14\","=>[{",\"15\","=>[{",\"11\","=>[{",\"12\","=>{"\"13\","=>[{",\"14\","=>[{",\"15\","=>[{",\"13\","=>[{",\"14\","=>[{",\"15\","=>[{"}"=>nil}]}]}]}]}]}]}}]}]}]}]}]}]}]}}]}}]}]}]}}]}]}]}]}]}]}]}}]}]}]}]}}} Completed 400 Bad Request in 1ms

But I need to make it work with large lists as well.

¿Fue útil?

Solución

The Rack utils.rb method to_params_hash does indeed recurse. It does that because, per http://api.jquery.com/jQuery.ajax/ , $.ajax() treats the data: variable as a string containing URL query parameters.

Put together, Rails treats each key in your nested structure as something that you want to see in your params hash. You don't; you just need to pass all that JSON as a string, so your own methods can safely decode it as JSON, using a C JSON library that (probably) won't abuse the stack.

Per jQuery ajax data two variables , you might be able to stuff the string into a hash and pass the hash:

var dataObj = {};
dataObj[json]=JSON.stringify({ sortd_items: sorted_items });
$.ajax({ ... data: dataObj });

​ Now $.ajax() won't see a string, won't convert it into query params, and won't bust Rack.

Otros consejos

I think this is a matter of properly setting the headers in the ajax request properly. You can post data that has been put through JSON.stringify, but the server won't know what to do with it unless you tell it what it's getting. This should fix it:

$.ajax({
  type: 'POST',
  url: '/projects',
  contentType: 'json',
  data: JSON.stringify({ sortd_items: sorted_items })
})
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top