I have to return a json to my frontend with a structure like this
{
"meta": {
"page": 1,
"pages": 1,
"perpage": -1,
"total": 40,
"sort": "asc",
"field": "RecordID"
},
"data": [
{
"RecordID": 1,
"OrderID": "61715-075",
"Country": "China",
"ShipCountry": "CN",
"ShipCity": "Tieba",
"ShipName": "Collins, Dibbert and Hoeger",
"ShipAddress": "746 Pine View Junction",
"CompanyEmail": "nsailor0#livejournal.com",
"CompanyAgent": "Nixie Sailor",
"CompanyName": "Gleichner, Ziemann and Gutkowski",
"Currency": "CNY",
"Notes": "imperdiet nullam orci pede venenatis non sodales sed tincidunt eu felis fusce posuere felis sed lacus morbi",
"Department": "Outdoors",
"Website": "irs.gov",
"Latitude": 35.0032213,
"Longitude": 102.913526,
"ShipDate": "2/12/2018",
"PaymentDate": "2016-04-27 23:53:15",
"TimeZone": "Asia/Chongqing",
"TotalPayment": "$246154.65",
"Status": 3,
"Type": 2,
"Actions": null
},
{
"RecordID": 2,
"OrderID": "63629-4697",
"Country": "Indonesia",
"ShipCountry": "ID",
"ShipCity": "Cihaur",
"ShipName": "Prosacco-Breitenberg",
"ShipAddress": "01652 Fulton Trail",
"CompanyEmail": "egiraldez1#seattletimes.com",
"CompanyAgent": "Emelita Giraldez",
"CompanyName": "Rosenbaum-Reichel",
"Currency": "IDR",
"Notes": "adipiscing elit proin risus praesent lectus vestibulum quam sapien varius ut blandit non interdum",
"Department": "Toys",
"Website": "ameblo.jp",
"Latitude": -7.1221059,
"Longitude": 106.5701927,
"ShipDate": "8/6/2017",
"PaymentDate": "2017-11-13 14:37:22",
"TimeZone": "Asia/Jakarta",
"TotalPayment": "$795849.41",
"Status": 6,
"Type": 3,
"Actions": null
},
{....}
]
}
I'm using a serializer with the Netflix json library.
I know how to return the collection:
render json: ContentSerializer.new(#contents).serializable_hash
Return me the data collection, but I cannot understand how can I add the 'meta' attribute
Related
I'm trying to render data from a API response (JSON) into my view.
For some reason i only can access the toplevel objects withouth any issues. BUt my knowledge is limited when it commes to retrieve the data from a nested object.
Woul appreciate if anybody can help me out.
controller.rb
require 'httparty'
class BlogController < ApplicationController
include HTTParty
def show
id = params[:id]
get("posts/#{id}")
end
def index
get('posts')
end
private
def get(path)
#host = 'api.example.com'
#blog = HTTParty.get('https://' + #host + '/' + path )
#post = HTTParty.get('https://' + #host + '/' + path )
return false if response.status != 200
puts response.body
end
end
view.html.erb
<p id="notice"><%= notice %></p>
<h2><%= #post["title"] %></h2>
<p><%= #post["description"] %></p>
<p><%= #post["content"] %></p>
<p><%= #post["heroimage.url"] %></p> <# This here is the problem how to render the url object which is part of "heroimage" parent
JSON response which i'm consuming:
{
"id": 1,
"title": "First Post",
"description": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam",
"content": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. \n\n![g-000261-g_W2615899_6-ktm-300-exc-637602315686776824.jpg](/uploads/g_000261_g_W2615899_6_ktm_300_exc_637602315686776824_a3b44fdf00.jpg)\n\n\nDuis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. ",
"author": null,
"created_at": "2021-10-28T21:31:10.445Z",
"updated_at": "2021-11-10T17:54:36.175Z",
"heroimage": {
"id": 1,
"name": "g-000261-g_W2615899_6-ktm-300-exc-637602315686776824.jpg",
"alternativeText": "",
"caption": "",
"width": 2048,
"height": 1536,
"formats": {
"large": {
"ext": ".jpg",
"url": "/uploads/large_g_000261_g_W2615899_6_ktm_300_exc_637602315686776824_a3b44fdf00.jpg",
"hash": "large_g_000261_g_W2615899_6_ktm_300_exc_637602315686776824_a3b44fdf00",
"mime": "image/jpeg",
"name": "large_g-000261-g_W2615899_6-ktm-300-exc-637602315686776824.jpg",
"path": null,
"size": 184.83,
"width": 1000,
"height": 750
},
"small": {
"ext": ".jpg",
"url": "/uploads/small_g_000261_g_W2615899_6_ktm_300_exc_637602315686776824_a3b44fdf00.jpg",
"hash": "small_g_000261_g_W2615899_6_ktm_300_exc_637602315686776824_a3b44fdf00",
"mime": "image/jpeg",
"name": "small_g-000261-g_W2615899_6-ktm-300-exc-637602315686776824.jpg",
"path": null,
"size": 50.69,
"width": 500,
"height": 375
},
"medium": {
"ext": ".jpg",
"url": "/uploads/medium_g_000261_g_W2615899_6_ktm_300_exc_637602315686776824_a3b44fdf00.jpg",
"hash": "medium_g_000261_g_W2615899_6_ktm_300_exc_637602315686776824_a3b44fdf00",
"mime": "image/jpeg",
"name": "medium_g-000261-g_W2615899_6-ktm-300-exc-637602315686776824.jpg",
"path": null,
"size": 110.16,
"width": 750,
"height": 563
},
"thumbnail": {
"ext": ".jpg",
"url": "/uploads/thumbnail_g_000261_g_W2615899_6_ktm_300_exc_637602315686776824_a3b44fdf00.jpg",
"hash": "thumbnail_g_000261_g_W2615899_6_ktm_300_exc_637602315686776824_a3b44fdf00",
"mime": "image/jpeg",
"name": "thumbnail_g-000261-g_W2615899_6-ktm-300-exc-637602315686776824.jpg",
"path": null,
"size": 10.56,
"width": 208,
"height": 156
}
},
"hash": "g_000261_g_W2615899_6_ktm_300_exc_637602315686776824_a3b44fdf00",
"ext": ".jpg",
"mime": "image/jpeg",
"size": 711.13,
"url": "/uploads/g_000261_g_W2615899_6_ktm_300_exc_637602315686776824_a3b44fdf00.jpg",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"created_at": "2021-11-10T16:22:27.152Z",
"updated_at": "2021-11-10T16:22:27.169Z"
}
}
As mentioned i'm trying to display the url (which is one level under "heroimage").
Shouldn't something like
#post[:heroimage][:url]
or
#post['heroimage']['url']
work?
With ruby, you should be able to treat the keys like a symbol. and ruby won't use dot notation in a hash so you would need to use square brackets.
You will have to convert response from json to Hash and for that use this:
parsed_response = JSON.parse(response.body)
After that it is just a hash so you can access simply like following:
parsed_response['heroimage']['url']
I would recommend to use dig here
parsed_response.dig('heroimage', 'url')
If you want a structured object then I would recommend to use RecursiveOpenStruct it will make all fields as nested object attributes
structured = RecursiveOpenStruct.new(parsed_response)
structured.heroimage.url
I'm developing an iOS app and need to make an Post request with a json object that looks like this:
{
"id": 30645,
"obj1": [
{
"id": 21649,
"comment":"Lorem ipsum dolor sit amet,",
"obj2": [
{
"id": 42070,
"comment": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum lacinia, urna sed gravida fringilla, elit",
"obj3": [
{
"id": 518964,
"active": false
}
],
"images": [UImage, UIImage, UIImage]
}
],
"status": 1
}
]
}
My question is: what is the best way to do this?
EDIT:
The issue is the array of UIImage, what can i do with that? Transform to base64 or use the multipart solution that Alamofire provides?
Thanks for your time.
P.D. I'm using Alamofire 4.0 and Swift 3
I'm trying to sort my data as a timeline:
[
{
"date": "1996-07-16T08:26:01 -02:00",
"isPublished": false,
"events": [
{
"title": "occaecat aliqua dolor sint",
"text": "Laboris nisi dolor ipsum pariatur veniam esse.",
"picture": "http://placehold.it/32x32",
"isPublished": true,
"tags": [
"elit",
"incididunt",
"consectetur"
]
},
...
},
{
"date": "1989-09-27T01:46:10 -01:00",
"isPublished": false,
"events": [
{
"title": "reprehenderit excepteur id minim",
"text": "Commodo id officia est irure proident duis. Occaecat",
"picture": "http://placehold.it/32x32",
"isPublished": false,
"tags": [
"ex",
"occaecat",
"commodo"
]
},
..
}
]
After reading some answers here on SO, I came with this so far:
class PagesController < ApplicationController
require 'httparty'
def index
response = HTTParty.get('https://raw.githubusercontent.com/valterhenrique/timeliner-sample/master/sample-data.json')
#dates = JSON.parse(response.body)
#sorted_dates = #dates.sort_by {|s| Date.strptime(s, '%Y-%m-%d')}
puts #new_dates
end
...
end
But I had no success so far. Any idea of how to sort these data by date ?
#dates.sort_by { |s| Date.parse(s["date"]) }
The above will produce a Date instance out of the string, that is stored under "date" key in each subsequent hash.
As #yzalavin properly noted in comments, you might want to instantiate DateTime to make the sorting better:
#dates.sort_by { |s| DateTime.parse(s["date"]) }
I am working on Rails 5 api only app.
So this is my model serializer
class MovieSerializer < ActiveModel::Serializer
attributes :id ,:name,:release_year,:story,:in_theater,:poster,:score,:user_count
belongs_to :age_rating
belongs_to :company
has_many :category , through: :movie_category
end
class CelebritySerializer < ActiveModel::Serializer
attributes :id, :first_name, :last_name
has_many :movie_celebrity
end
class MovieCelebritySerializer < ActiveModel::Serializer
attributes :id,:vacancy,:title
belongs_to :movie
belongs_to :celebrity
end
This is my controller
class Api::V1::MoviesController < ApplicationController
# GET /v1/movies/:id
def show
movie = Movie.find_by(id: params[:id])
casts = MovieCelebrity.where(movie_id: params[:id],vacancy: "cast")
directors = MovieCelebrity.where(movie_id: params[:id],vacancy: "director")
render :json => {:movie => movie, :casts => casts , :directors => directors}
end
end
So this is what i got when i made a request
{
"movie": {
"id": 1,
"name": "0 The Doors of Perception",
"release_year": 2007,
"story": "Non doloribus qui et eum impedit. Rerum mollitia debitis sit nesciunt. Vero autem quae sit aliquid rerum ex fugit. Eligendi assumenda et eos. Blanditiis hic ut. Commodi quo sunt voluptatem quasi.",
"in_theater": false,
"age_rating_id": 2,
"company_id": 5,
"created_at": "2016-10-12T12:45:26.213Z",
"updated_at": "2016-10-12T12:45:26.213Z",
"release_date": "2016-01-18",
"poster": "'http://cdn.mos.cms.futurecdn.net/15399e7a7b11a8c2ef28511107c90c6f.jpg',",
"score": 0,
"user_count": 6950
},
"casts": [
{
"id": 2,
"vacancy": "cast",
"title": "Pro x",
"movie_id": 1,
"celebrity_id": 56,
"created_at": "2016-10-12T12:45:28.001Z",
"updated_at": "2016-10-12T12:45:28.001Z"
},
{
"id": 3,
"vacancy": "cast",
"title": "Magneto",
"movie_id": 1,
"celebrity_id": 23,
"created_at": "2016-10-12T12:45:28.006Z",
"updated_at": "2016-10-12T12:45:28.006Z"
}
],
"directors": [
{
"id": 1,
"vacancy": "director",
"title": "",
"movie_id": 1,
"celebrity_id": 17,
"created_at": "2016-10-12T12:45:27.993Z",
"updated_at": "2016-10-12T12:45:27.993Z"
}
]
}
It seems like Active model serializer did not work.
Because if i only return one object it worked fine like this.
def show
movie = Movie.find_by(id: params[:id])
casts = MovieCelebrity.where(movie_id: params[:id],vacancy: "cast")
directors = MovieCelebrity.where(movie_id: params[:id],vacancy: "director")
#render :json => { :movie => movie, :casts => casts , :directors => directors }
render :json => movie
end
{
"id": 1,
"name": "0 The Doors of Perception",
"release_year": 2007,
"story": "Non doloribus qui et eum impedit. Rerum mollitia debitis sit nesciunt. Vero autem quae sit aliquid rerum ex fugit. Eligendi assumenda et eos. Blanditiis hic ut. Commodi quo sunt voluptatem quasi.",
"in_theater": false,
"poster": "'http://cdn.mos.cms.futurecdn.net/15399e7a7b11a8c2ef28511107c90c6f.jpg',",
"score": 0,
"user_count": 6950,
"age_rating": {
"id": 2,
"name": "PG"
},
"company": {
"id": 5,
"name": "Gislason, Jacobs and Graham"
},
"category": [
{
"id": 4,
"name": "Biography"
},
{
"id": 16,
"name": "Mystery"
}
]
}
How can i fixed this and make the Active model serializer works fine with multiple models hash object?
Thanks!
You need to set explicit serializer like this:
render json: {movie: movie, casts: casts , directors: directors}, serializer: MovieCastDirectorSerializer
Because AMS doesn't know which serializer needed for your plain ruby object that you construct here.
Update:
But even if you do so, AMS still will be unable to serialize that as it will be not ActiveModel object. There is an example of how to deal with that. But for me personally, it seems too much like a hack. I think you should not abuse REST so early and should separate serializers by actual end-points and only nest resources if they are nested in the real structure. Because later as your code matures it'll be really difficult to tell where you getting that data you see on display after all.
I have this http://localhost:3000/api/products request that returns json format output with a list of products objects. I heard in some scenario its better to use multi-gets design where you list products ids in URI like so http://localhost:3000/api/products?ids=1,2,3,4. My question is how do i configure the route to return such an URI? Below is the json output returned by http://localhost:3000/api/products.Thank you in advance
controller
def index
#products=Product.all
respond_to do |format|
format.json { render json: #products.to_json}
format.xml
end
end
json output
[
{
"category_id": null,
"created_at": "2011-03-25T13:35:16Z",
"details": "Molestias pariatur consequuntur ut voluptas aperiam facere et et autem ad laudantium ut qui dolorem iste sit ut in dignissimos. Et debitis et et sunt quidem qui est est et numquam in dolorum natus sapiente nihil ipsa ratione. Quisquam aut molestiae earum voluptas vero et officiis magnam quam provident voluptatibus quia",
"id": 1,
"product_name": "Velit",
"publisher_id": 1,
"updated_at": "2012-11-12T18:45:13Z",
"publisher_details": "http://localhost:3000/api/users/1"
},
{
"category_id": null,
"created_at": "2012-01-10T23:16:53Z",
"details": "Temporibus quis et quam eveniet hic consequatur maiores eum expedita molestiae velit eligendi laboriosam ut molestiae. Velit delectus aliquid nobis quia velit aut dolorem omnis numquam reprehenderit quo illo saepe molestiae nisi. Soluta nihil quae soluta facilis cumque voluptates eaque amet unde non in placeat id cupiditate illum at et vero. Laborum id eaque voluptas illo eius iure",
"id": 2,
"product_name": "Nam Laboriosam Et Sed",
"publisher_id": 1,
"updated_at": "2012-11-12T18:45:13Z",
"publisher_details": "http://localhost:3000/api/users/1"
}]
There is a gem, which is discontinued, which was written for sproutcore (now ember) that offered this out of the box: https://github.com/drogus/bulk_api
But actually, it does not have to be that hard at all. For a single controller I would just do something like
def index
ids = params[:ids]
if ids.blank?
#categories = Category.all
else
wanted_ids = ids.split(',')
#categories = Categoriy.where(:id => wanted_ids)
end
render :json => #categories
end
Does that help?