0

How to post multiple rows into DB using ruby Grape. For example when testing with CURL this is working fine

curl -H "Content-Type: application/json" -X POST \
     -d '{"name": "test", "age": "22"}' http://localhost:3000/students

But this is not working

curl -H "Content-Type: application/json" -X POST \
     -d '[{"name": "test", "age": "22"}, {"name": "someone", "age": "32" }]' \
     http://localhost:3000/students

This is my grape api code

post do
      student = Student.new
      student.name = params[:name]
      student.age = params[:age]
      student.save!
end
Neil Slater
  • 26,512
  • 6
  • 76
  • 94
ejo
  • 446
  • 1
  • 9
  • 23
  • 1
    Use an array as json top element: `-d '[{"name": "test", "age": "22"}, {"name": "someone", "age": "32" }]'` – Aleksei Matiushkin Nov 25 '15 at 09:30
  • As your question is about Grape, if the POST method you have implemented does not support arrays as suggested by mudasobwa, then you should show the Ruby code for `post :students` route, and maybe related helper and/or entity. Note it is quite common (and not incorrect) to have a RESTful API that only creates one object at a time, that you must call multiple times in order to create multiple objects. – Neil Slater Nov 25 '15 at 09:40
  • Your Grape API code is fine, but clearly does not support receiving a JSON Array. It is not a normal expectation that it should though. Just send multiple requests to create multiple student objects. – Neil Slater Nov 25 '15 at 10:39
  • Thanks @Neil Slater. But my requirement is related to batch insert. How I can achieve this using GRAPE – ejo Nov 25 '15 at 11:55
  • @ejo: Does your requirement insist that you use JSON array syntax as shown, or is that flexible? It may be easier to implement if the route had an outer JSON structure, with a param name to identify the array, and it would also be easier to support the batch insert syntax on a different route (otherwise you would need to detect and disambiguate between two route method signatures) – Neil Slater Nov 25 '15 at 12:39
  • I didn't get it completely. Could you give some sample structure according to your suggestion? – ejo Nov 25 '15 at 13:25
  • Example: Have a new route `POST http://localhost:3000/students/bulk_insert` which accepts JSON object like this `'{"students":[{"name": "test", "age": "22"}, {"name": "someone", "age": "32" }]}'` - if your design constraints allow you to do that, the Grape setup is trivial. But if you are expected to allow POSTs of JSON arrays in general to any standard object creation route, whilst still supporting single item creation, it is a lot harder. – Neil Slater Nov 26 '15 at 11:19

1 Answers1

0

You use a bad syntax for JSON array object. Try this:

curl -H "Content-Type: application/json" \
     -X POST \
     -d '[{"name": "test", "age": "22"}, {"name": "someone", "age": "32" }]' \
     http://localhost:3000/students

EDIT :

If your payload is {"name": "test", "age": "22"} your code works. But you have a Array (params.kind_of?(Array)).

You can make this:

post do
  params.each do |student_params|
    student = Student.new
    student.name = student_params[:name]
    student.age = student_params[:age]
    student.save!
  end
end

Explanation:

params[:name]
# => nil
params.first[:name]
#=> test
Gearnode
  • 693
  • 7
  • 21