How to allow top-level JSON array param in Ruby Grape - ruby

I have a route with /coordinates. I want to receive a JSON Array on this route, such as:
[
{"latitude": 1, "longitude": 1},
{"latitude": 1, "longitude": 2},
{"latitude": 1, "longitude": 3}
]
How do I configure the params to parse this kind of data with grape? I don't want to give a name to the array such as { "blah": []}, I just want to read it from the request.
Here's what I'm trying to do
params do
requires :latitude, type: Float
requires :longitude, type: Float
end
post do
route = Route.create(coordinates: params)
{ id: route.id }
end

Related

Enforce that a Grape Entity always returns an array?

How can I enforce that my Grape Entity always returns an array (collection) even if its just a singular object? I have heard that some people create a helper method that gets called inside their endpoint, but I have not found any examples of anyone doing that, online.
The default functionality of an Entity is that it returns an object if only a single document (mongoid object) is returned. If a collection of documents is returned then it returns an array, I dont want my client application having to do a check every time to see if an object or an array got returned from my API.
## Resource (HTTP Endpoint)
desc 'List departments a user can and cannot access'
params do
requires :user_id
end
get :department_access do
#user = BACKBONE::User.find(#access_key.user_id)
requires_admin!
user = BACKBONE::User.find(params[:user_id])
can_access = BACKBONE::Department.user_can_access(user)
no_access = BACKBONE::Department.user_cannot_access(user)
present_success can_access
present :can_access, can_access, with: BACKBONE::Entities::DepartmentBase
present :no_access, no_access, with: BACKBONE::Entities::DepartmentBase
end
-
## Entity
module BACKBONE
module Entities
class DepartmentBase < BACKBONE::Entities::Mongoid
expose :name
expose :prefix
with_options(format_with: :mongo_id) do
expose :company_id
end
end
end
end
JSON Response
{
"status": "success",
"request_time": 0.009812,
"records": 1,
"can_access": {
"id": "59699d1a78cee4f8d07528fc",
"created_at": "2017-07-14T21:42:02.666-07:00",
"updated_at": "2017-07-14T21:42:02.666-07:00",
"name": "Tenant Improvement",
"prefix": "CACC",
"company_id": "596927fb670f6eec21c4f409"
},
"no_access": {
"id": "59699cca78cee4f8d07528fb",
"created_at": "2017-07-14T21:40:42.005-07:00",
"updated_at": "2017-07-14T21:40:42.005-07:00",
"name": "Field Operations",
"prefix": "CACC",
"company_id": "596927fb670f6eec21c4f409"
}
}
a coworker and I came up with a solution with a helper, create a helper method that always returns an array:
def present_array(key, data, entity)
d = (data.class.respond_to? :count) ? [data] : data
d = [] if d.nil?
present key, d, entity
end

HTTPI unable to pass array params

#request.url = url
#request.headers = {"Content-Type" => "application/x-www-form-urlencoded; charset=utf-8"}
#request.body = {a: "1", b: "2", c: [{d: "3"}, {e: "4"}]}
The problem is that the server side could receive params like a or b, but each value of c is null, like "c": [{"d": null}, {"e": null}]. Any help will be appreciated.
[Solved] :) The server use .net and I don't know what they did..

RABL - How to create a custom child node as collection?

{
total: 250,
page: 3,
data: [
{ id: 1, name: "Foo", ...},
{ id: 2, name: "Bar", ...}
]
}
I want to create structure like this. Value of id and name are random. It is not saved any variable.
If all you are searching is how to make custom nodes is just with node method.When you declare object to be false you are free to make just custom repsonse.Here is a solution where I generate ids from 1 to 100, and name based on simple conversation to hexademical numbers.
object false
node(:total) { |m| #total }
node(:page) { |m| #page }
node(:data) do |m|
1.upto(100).map { |id| Hash[[[:id, id], [:name, (id * 143223).to_s(16)]]] }
end

make json from params hash

I am trying to call API and pass data to it from the form in my view to controller and then call API with post method.
What I get in params is:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"kLLaVRc6kcndkfB1nkntSTzGCg95CMCT1UvEncqwLgc=",
"score_sheet"=>{
"score_sheet_master"=>{
"issue_date(1i)"=>"2014", "issue_date(2i)"=>"6", "issue_date(3i)"=>"27"},
"print_date(1i)"=>"2014", "print_date(2i)"=>"6", "print_date(3i)"=>"27", "product_id"=>"2", "pull_id"=>"2", "press_run_id"=>"1", "total_section"=>"2",
"score_sheet_sections_attributes"=>{
"0"=>{"section_name"=>"A", "total_pages"=>"2", "color_pages"=>"1", "_destroy"=>"false"},
"1"=>{"section_name"=>"B", "total_pages"=>"1", "color_pages"=>"", "_destroy"=>"false"}},
"color_pages_rated"=>"1", "bw_pages_rated"=>"2", "foreman_id"=>"", "pic_id"=>""},
"score_sheet_master"=>{
"press_id"=>"1"},
"commit"=>"Create Score sheet"}
I want this Hash to be converted into the Following JSON which APIs accept. i-e.
{
"score_sheet": {
"score_sheet_master": {
"issue_date": "2014-06-25",
"press_id": "1"
},
"print_date": "2014-06-23",
"product_id": 1,
"pull_id": 2,
"press_run_id": 1,
"total_section": 2,
"score_sheet_sections_attributes": [
{
"section_name": "A",
"total_pages": 3,
"color_pages": "2,3",
"id": 9
},
{
"section_name": "B",
"total_pages": 1,
"color_pages": "1",
"id": 10
},
{
"section_name": "C",
"total_pages": 2,
"color_pages": "2"
}
],
"pic_id": 1,
"foreman_id": 1
}
}
Some the fields in JSON might be missing or may be more than the HASH but I don't have concern with that I will handle them personally the main issue is to convert this params Hash to the required JSON. Hold On I have implemented the date conversion thing that is working fine. but don't know how to convert score_sheet_sections_attributes array format to the required format.
Oh Got it myself:
sections = []
params["score_sheet"]["score_sheet_sections_attributes"].each {|k,v| sections << v}
params["score_sheet"]["score_sheet_sections_attributes"] = sections
Which gives:
{"utf8"=>"✓", "authenticity_token"=>"kLLaVRc6kcndkfB1nkntSTzGCg95CMCT1UvEncqwLgc=", "score_sheet"=>{"score_sheet_master"=>{"issue_date(1i)"=>"2014", "issue_date(2i)"=>"6", "issue_date(3i)"=>"27"}, "print_date(1i)"=>"2014", "print_date(2i)"=>"6", "print_date(3i)"=>"27", "product_id"=>"2", "pull_id"=>"2", "press_run_id"=>"1", "total_section"=>"2", "score_sheet_sections_attributes"=>[{"section_name"=>"A", "total_pages"=>"2", "color_pages"=>"1", "_destroy"=>"false"}, {"section_name"=>"B", "total_pages"=>"1", "color_pages"=>"", "_destroy"=>"false"}], "color_pages_rated"=>"1", "bw_pages_rated"=>"2", "foreman_id"=>"", "pic_id"=>""}, "score_sheet_master"=>{"press_id"=>"1"}, "commit"=>"Create Score sheet"}
and for dates I have another logic implemented and all done.

django: Testing POST-based views with json objects

I have a django application with several views that accept json objects via POST requests. The json objects are medium-complex with a few layers of nesting, so I'm using the json library to parse raw_post_data, as shown here:
def handle_ajax_call(request):
post_json = json.loads(request.raw_post_data)
... (do stuff with json query)
Next, I want to write tests for these views. Unfortunately, I can't figure out how to pass the json object to the Client. Here's a simplest-case version of my code:
def test_ajax_call(self):
c = Client()
call_command('loadfixtures', 'temp-fixtures-1') #Custom command to populate the DB
J = {
some_info : {
attr1 : "AAAA",
attr2 : "BBBB",
list_attr : [ "x", "y", "z" ]
},
more_info : { ... },
info_list : [ 1, 22, 23, 24, 5, 26, 7 ]
}
J_string = json.dumps(J)
response = c.post('/ajax/call/', data=J_string )
When I run the test, it fails with:
AttributeError: 'str' object has no attribute 'items'
How can I pass the JSON object in the Client.post method?
The documentation seems to imply that if you pass a content_type parameter to client.post, it will treat the data value as a document and POST it directly. So try this:
response = c.post('/ajax/call/', content_type='application/json', data=J_string)

Resources