make json from params hash - ruby

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.

Related

How to reference enum value in API Blueprint(MSON)

I'm using API Blueprint and Agilo to render my API documentation. When using enum type, I'm observing a weird behavior. The response is not shown with the defined enum value whereas the schema is showing all the enum values (which is expected) along with the declared value ('Monday'- Refer Actual) as well.
Data Structure section
# Data Structures
## Days (enum[string])
+ `Monday`
+ `Tuesday`
+ `Wednesday`
+ `Thursday`
## ListEntry
- playOrder: 1 (number)
- Id: 37a21975a499494f03367 (string)
- programDay: `Tuesday` (Days)
## `sample-request-200`
- id: 58828b2941cc351348 (string)
- startDate: `2019-08-01T11:00:00.000Z` (string)
- endDate: `2019-08-05T11:55:59.000Z` (string)
- Language: `en-US` (string)
- entries: ListEntry (array[object])
API Request Doc section
+ Request
+ Headers
Content-Type: application/json
+ Attributes (sample-request-200)
Actual
---- JSON Body ----
{
"playOrder": 1,
"Id": "37a21975a499494f03367",
"programDay": "Hello, world!" // Agilo shows "Hello,World" when some error occurred
}
-----Generated Schema-----
"programDay": {
"type": "string",
"enum": [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Monday"
]
}
Desired
---- JSON Body ----
{
"playOrder": 1,
"Id": "37a21975a499494f03367",
"programDay": "Monday"
}
-----Generated Schema-----
"programDay": {
"type": "string",
"enum": [
"Monday",
"Tuesday",
"Wednesday",
"Thursday"
]
}
Any idea on how to use the defined enum data structure in API blueprint (MSON). Not sure how to reference an enum value in the Object.
Is it right to use as below to reference an enum value?
- programDay: `Tuesday` (Days)
Structure:
# Data Structures
## Device (enum)
+ `mobile`
+ `desktop`
Use like this:
+ Request (multipart/form-data)
+ Attributes
+ `id`: abc (required)
+ `device` (Device)
Results:

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

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

Laravel 5.1 Date_Format Validator Fails on Y-m-d Format

I'm starting to use Request objects to validate incoming post data, and I've seen examples of how others are using date_format, but I can't seem to get dates to pass even though I'm using a format that passes when you use PHP's date_parse_from_format:
print_r(date_parse_from_format('Y-m-d','2015-07-27'));
Output
UPDATE: their is a warning in date_parse_from_format, but I don't understand why as it reflects the format.
{
"year": 2015,
"month": 2,
"day": 30,
"hour": false,
"minute": false,
"second": false,
"fraction": false,
"warning_count": 1,
"warnings": {
"10": "The parsed date was invalid"
},
"error_count": 0,
"errors": [],
"is_localtime": false
}
Validator
public function rules()
{
return [
'rental_id' => 'required|exists:rentals,id',
'start_at' => 'required|date_format:Y-m-d',
'end_at' => 'required|date_format:Y-m-d'
];
}
Using PostMan I'm sending in a payload of:
rental_id = 1 as text
start_at = 2015-02-30 as text
end_at = 2015-02-30 as text
And it throws a NotFoundHttpException, but if I comment out start_at and end_at in the validator request it passes, and enters my controllers action with the proper payload:
{
"rental_id": "1",
"start_at": "2015-02-30",
"end_at": "2015-02-30"
}
Apparently, the date_format validation failed as I randomly chose 2015-02-30 to test my API, but that day doesn't exist as that would be February 30... oh the shame and the wasted time. Thanks to #ceejayoz for all the help!!!

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)

Parsing Mulitlevel Javascript Objects in Grails 2.1

I am trying to send data to my controller from an ajax function that needs to have multiple levels, so something like this:
{
"lob": {
"TESTING": [
{
"name": "color",
"value": "1"
},
{
"name": "time",
"value": "2"
},
{
"name": "jeremy",
"value": "3"
},
{
"name": "fourtytwo",
"value": "4"
},
{
"name": "owl",
"value": "5"
},
{
"name": "why",
"value": "6"
},
{
"name": "derp",
"value": "7"
},
{
"name": "where",
"value": "8"
}
]
}
}
but when it sends to grails I am getting this when I print out the params
[lob[TESTING][4][value]:5,
lob[TESTING][3][name]:fourtytwo,
lob[TESTING][6][name]:derp,
lob[TESTING][5][name]:why,
lob[TESTING][3][value]:4,
lob[TESTING][1][value]:2,
lob[TESTING][2][value]:3,
lob[TESTING][5][value]:6,
lob[TESTING][1][name]:time,
lob[TESTING][0][value]:1,
lob[TESTING][6][value]:7,
lob[TESTING][0][name]:color,
lob[TESTING][7][value]:8,
lob[TESTING][4][name]:owl,
lob[TESTING][7][name]:where,
lob[TESTING][2][name]:jeremy,
action:save,
controller:LOB]
The data I am sending from JavaScript:
{
lob: {
TESTING: $form.serializeArray()
}
}
I have been reading multiple forums saying using JSON.parse or request.JSON but these solutions do not seem to be fixing my problems. I want to be able to access the data like
params.lob.testing.each{ a->
println a
}
I will be doing alot more than just that but it would be nice to be able to access the data in that fashion. I am using Grails 2.1 and Jquery 1.7.2
Actually Grails makes it very easy. I've taken your test data and ran it through the following:
import grails.converters.JSON
class LobController {
def save = {
def json = request.JSON
json.lob.TESTING.each {item->
println "Name: ${item.name} - Value: ${item.value}"
}
//render something back if you need to here
}
}
And it outputs:
Name color - Value: 1
Name time - Value: 2
Name jeremy - Value: 3
Name fourtytwo - Value: 4
Name owl - Value: 5
Name why - Value: 6
Name derp - Value: 7
Name where - Value: 8
I created a UrlMapping entry like this (you probably already have this):
"/myApi"(controller: "lob", parseRequest: true) {
action = [POST: "save"]
}
The parseRequest: true will automatically parse the incoming JSON.
I found a `serializeJSON' function that might replace the serializeArray() to format this for JSON. The following was provided by Arjen Oosterkamp on the jQuery serializeArray page:
(function( $ ){
$.fn.serializeJSON=function() {
var json = {};
jQuery.map($(this).serializeArray(), function(n, i){
json[n['name']] = n['value'];
});
return json;
};
})( jQuery );
Simply use as $('form').serializeJSON();
All credit for that function goes to Arjen Oosterkamp...

Resources