Parse JSON from HTTParty using Ruby on Rails - ruby-on-rails

I am implementation of data from a JSON file to a Ruby on Rails application by using HTTparty gem, but I am getting Error no implicit conversion of String into Integer
I refered this tutorial link
My json data,
{
"restaurant_name": "Restaurant 3",
"address": "xyz address",
"country": "United States",
"currency": "USD",
"client_key": "12345",
"client_name": "Client 3",
"client_email": "test3#mail.com",
"client_phone": "9876",
"product_tier": "tier1",
"brand_logo_large": {
"ID": 37,
"id": 37,
"title": "bait-al-bahar-logo-design",
"filename": "bait-al-bahar-logo-design.png",
"filesize": 105071,
"url": "http://codekyt.in/froodle-wp/wp-content/uploads/2019/01/bait-al-bahar-logo-design.png",
"link": "http://codekyt.in/froodle-wp/projects/res-1-client-1/bait-al-bahar-logo-design/",
"alt": "",
"author": "1",
"description": "",
"caption": "",
"name": "bait-al-bahar-logo-design",
"status": "inherit",
"uploaded_to": 35,
"date": "2019-01-04 11:11:48",
"modified": "2019-01-04 11:13:01",
"menu_order": 0,
"mime_type": "image/png",
"type": "image",
"subtype": "png",
"icon": "http://codekyt.in/froodle-wp/wp-includes/images/media/default.png",
"width": 600,
"height": 500,
"sizes": {
"thumbnail": "http://codekyt.in/froodle-wp/wp-content/uploads/2019/01/bait-al-bahar-logo-design-150x150.png",
"thumbnail-width": 150,
"thumbnail-height": 150,
"medium": "http://codekyt.in/froodle-wp/wp-content/uploads/2019/01/bait-al-bahar-logo-design-300x250.png",
"medium-width": 300,
"medium-height": 250,
"medium_large": "http://codekyt.in/froodle-wp/wp-content/uploads/2019/01/bait-al-bahar-logo-design.png",
"medium_large-width": 600,
"medium_large-height": 500,
"large": "http://codekyt.in/froodle-wp/wp-content/uploads/2019/01/bait-al-bahar-logo-design.png",
"large-width": 600,
"large-height": 500
}
}
In model,
include HTTParty
In controller
def index
require 'httparty'
#category = HTTParty.get(
'http://codekyt.in/froodle-wp/wp-json/data/v2/projects?client_key=12345',
:headers =>{'Content-Type' => 'application/json'}
)
end
In gemfile,
gem 'httparty'
gem 'json'
In view,
<%#category.each do |category|%>
<%=category["restaurant_name"]%>
<%=category["country"]%>
<%=category["currency"]%>
<%=category["usd"]%>
<%=category["client_key"]%>
<%=category["client_name"]%>
<%=category["client_email"]%>
<%=category["client_phone"]%>
<%=category["product_tier"]%>
<%=category["brand_logo_large"]%>
<%end%>

HTTParty.get returns an encapsulated response type of class HTTParty::Response, you need to retrieve the parsed response from that by:
response = HTTParty.get(
'http://codekyt.in/froodle-wp/wp-json/data/v2/projects?client_key=12345',
:headers =>{'Content-Type' => 'application/json'}
)
#category = response.parsed_response # this will return the json.
Also you do not need to iterate on #category in your case, the json object is singular and you can directly use it:
<%=#category["restaurant_name"]%>
<%=#category["country"]%>
<%=#category["currency"]%>
<%=#category["usd"]%>
<%=#category["client_key"]%>
<%=#category["client_name"]%>
<%=#category["client_email"]%>
<%=#category["client_phone"]%>
<%=#category["product_tier"]%>
<%=#category["brand_logo_large"]%>

Related

How to nest another value inside a nested objectin Jbuilder in Rails/Ruby

Here's my jbuilder file:
json.actor_avatar_url notification.actor.avatar.blob.service_url if notification.actor.avatar.attached?
json.actor notification.actor
Which gets me this output:
{
"actor_avatar_url": "http://res.imageurl.com/testimage/etc",
"actor": {
"id": 151,
"allow_password_change": false,
"username": "test test",
"email": "test4#test.com",
"created_at": "2021-03-27T17:52:08.866Z",
"updated_at": "2021-04-06T22:56:26.845Z",
}
}
But I want to get this output:
{
"actor": {
"actor_avatar_url": "http://res.imageurl.com/testimage/etc",
"id": 151,
"allow_password_change": false,
"username": "test test",
"email": "test4#test.com",
"created_at": "2021-03-27T17:52:08.866Z",
"updated_at": "2021-04-06T22:56:26.845Z",
},
}
With the avatar_url somehow placed inside of the nested object.
But this of course doesn't work:
json.actor do
notification.actor
json.actor_avatar_url notification.actor.avatar.blob.service_url if notification.actor.avatar.attached?
end
How would I accomplish this?
Thanks!

How can I save external JSON data to DB(sqlite) with Rails

I have a form to add json url form, If user add json url and submit form, I want to save all json data to db.[form]1
Fetching json data from url using httparty gem works perfectly, now to store json data to db json_url
json data
{
"restaurant_name": "Restaurant 3",
"address": "xyz address",
"country": "United States",
"currency": "USD",
"client_key": "12345",
"client_name": "Client 3",
"client_email": "test3#mail.com",
"client_phone": "9876",
"product_tier": "tier1",
"brand_logo_large": {
"ID": 37,
"id": 37,
"title": "bait-al-bahar-logo-design",
"filename": "bait-al-bahar-logo-design.png",
"filesize": 105071,
"url": "http://codekyt.in/froodle-wp/wp-content/uploads/2019/01/bait-al-bahar-logo-design.png",
"link": "http://codekyt.in/froodle-wp/projects/res-1-client-1/bait-al-bahar-logo-design/",
"alt": "",
"author": "1",
"description": "",
"caption": "",
"name": "bait-al-bahar-logo-design",
"status": "inherit",
"uploaded_to": 35,
"date": "2019-01-04 11:11:48",
"modified": "2019-01-04 11:13:01",
"menu_order": 0,
"mime_type": "image/png",
"type": "image",
"subtype": "png",
"icon": "http://codekyt.in/froodle-wp/wp-includes/images/media/default.png",
"width": 600,
"height": 500,
"sizes": {
"thumbnail": "http://codekyt.in/froodle-wp/wp-content/uploads/2019/01/bait-al-bahar-logo-design-150x150.png",
"thumbnail-width": 150,
"thumbnail-height": 150,
"medium": "http://codekyt.in/froodle-wp/wp-content/uploads/2019/01/bait-al-bahar-logo-design-300x250.png",
"medium-width": 300,
"medium-height": 250,
"medium_large": "http://codekyt.in/froodle-wp/wp-content/uploads/2019/01/bait-al-bahar-logo-design.png",
"medium_large-width": 600,
"medium_large-height": 500,
"large": "http://codekyt.in/froodle-wp/wp-content/uploads/2019/01/bait-al-bahar-logo-design.png",
"large-width": 600,
"large-height": 500
}
}
}
I created a form to user & added json url,
<%= form_tag("/settings/json_url", method: "post") do %>
<%= label_tag :json_url %>
<%= text_field_tag :json_url %>
<%= submit_tag 'submit' %>
<% end %>
In db,
t.string :key
t.string :value
t.string :json_url
In controller,
def json_url
# I am getting confused here
end

Mapping JSON Response to Model

New to the notion of Rails mapping, and would love to get some help on this from the stack overflow community.
Currently I have this JSON response from the Embedly API and don't really know how to map it to my very simple 'posts' model. I'm trying to get the image/title/url from the JSON response and map it into my database in the relevant fields, so in the JSON response below these would be 'original_url', 'image' and 'title'.
{
"provider_url": "http://piccsy.com",
"authors": [],
"provider_display": "piccsy.com",
"related": [],
"favicon_url": "http://piccsy.com/favicon.ico",
"keywords": [],
"app_links": [],
"original_url": "http://piccsy.com/2015/02/rihanna-sharks-harpers-bazaar-march-2015-photoshoot3",
"media": {},
"content": null,
"entities": [],
"provider_name": "Piccsy",
"type": "html",
"description": "Beautiful, inspirational and creative images from Piccsy. Thousands of Piccs from all our streams, for you to browse, enjoy and share with a friend.",
"embeds": [],
"images": [
{
"width": 728,
"url": "http://img2.piccsy.com/cache/images/56/8f/bed__396d8_cecf850824130_99f-post.jpg",
"height": 1092,
"caption": null,
"colors": [
{
"color": [
190,
211,
212
],
"weight": 0.3095703125
},
{
"color": [
114,
159,
171
],
"weight": 0.247314453125
},
{
"color": [
0,
52,
68
],
"weight": 0.244140625
},
{
"color": [
25,
99,
117
],
"weight": 0.198974609375
}
],
"entropy": 5.94797179868,
"size": 318918
},
{
"width": 200,
"url": "http://piccsy.com/piccsy/images/layout/logo/e02f43.200x200.jpg",
"height": 200,
"caption": null,
"colors": [
{
"color": [
215,
51,
67
],
"weight": 0.701904296875
},
{
"color": [
250,
252,
252
],
"weight": 0.298095703125
}
],
"entropy": 0.686638083774,
"size": 18691
}
],
"safe": true,
"offset": null,
"cache_age": 86065,
"lead": null,
"language": null,
"url": "http://piccsy.com/2015/02/rihanna-sharks-harpers-bazaar-march-2015-photoshoot3",
"title": "Rihanna-sharks-harpers-bazaar-march-2015-photoshoot3",
"favicon_colors": [
{
"color": [
208,
37,
38
],
"weight": 0.000244140625
},
{
"color": [
0,
0,
0
],
"weight": 0.000244140625
}
],
"published": null
}
My posts model contains very simple name, url and image fields which are all accepting strings. Any help on mapping this to a model would be brilliant, up till now I've only done very simple JSON responses and this one is a bit out of my league.
Thanks for your time.
You can just parse json response, and get required fields from it
json_response = '{your json response from api}'
response_hash = JSON.parse(json_response)
MyModel.create!(url: response_hash[:original_url], title: response_hash[:title])
But there is problem with images, response contains multiple images, so probably you should have ImageModel that belongs to MyModel, and MyModel has_many ImageModels.
Then you can do:
model = MyModel.create!(url: response_hash[:original_url], title: response_hash[:title])
response_hash[:images].each do |image|
model.images.create!(url: image[:url])
end

how to make this method more efficient Rails 3?

i want to make my method more efficient. my method take so much time in response. so please edit my code to get more efficient response.i am very thank full to you if you make this method more more efficient. and you are master in ruby on rails then if you can make this method with joins then what a wounder full method is it for me.
thanks
def all_shows_with_videos
#arr = []
tvs = Tv.all
tvs.each do |tv|
tv_tmp = {:name => tv.name, :id => tv.id}
tv_tmp[:videos] = tv.videos
tv_tmp[:seasons] = []
season_tmp = {}
tv.seasons.each do |season|
season_tmp = {:name => season.name, :id => season.id}
season_tmp[:videos] = season.videos
season_tmp[:episodes] = []
season.episodes.each do |episode|
season_tmp[:episodes] << {:name => episode.name, :id => episode.id} if episode.videos?
end
tv_tmp[:seasons].push(season_tmp) if !season_tmp[:videos].blank? or !season_tmp[:episodes].blank?
end
#arr.push(tv_tmp) if !tv_tmp[:videos].blank? or !tv_tmp[:seasons].blank?
end
#arr = Kaminari.paginate_array(#arr).page(params[:page]).per(5)
respond_to do |format|
format.json {render :json => #arr}
end
end
and output is
[
{
"name": "Iron Man",
"id": 95,
"videos": [
{
"id": 1,
"name": "Trailer 1",
"site": "Youtube.com",
"link": "Google.com",
"quality": null,
"video_type": null,
"videoable_id": 95,
"videoable_type": "Tv",
"created_at": "2014-05-26T07:05:39+05:00",
"video_source": null,
"video_source_cd": null
}
],
"seasons": []
},
{
"name": "How I Met Your Mother",
"id": 100,
"videos": [
{
"id": 13,
"name": "Trailer 1",
"site": null,
"link": "google.com",
"quality": "1020",
"video_type": "Trailer",
"videoable_id": 100,
"videoable_type": "Tv",
"created_at": "2014-06-09T10:05:03+05:00",
"video_source": null,
"video_source_cd": null
}
],
"seasons": []
},
{
"name": "my tv",
"id": 124,
"videos": [
{
"id": 59,
"name": "Trailer 1",
"site": null,
"link": "google.com",
"quality": "1020",
"video_type": "Trailer",
"videoable_id": 124,
"videoable_type": "Tv",
"created_at": "2014-06-20T06:59:32+05:00",
"video_source": null,
"video_source_cd": null
}
],
"seasons": []
},
{
"name": "Game of Thrones",
"id": 151,
"videos": [
{
"id": 129,
"name": "",
"site": null,
"link": null,
"quality": null,
"video_type": "Season",
"videoable_id": 151,
"videoable_type": "Tv",
"created_at": "2014-09-02T11:13:40+05:00",
"video_source": null,
"video_source_cd": null
},
{
"id": 130,
"name": "",
"site": null,
"link": "",
"quality": null,
"video_type": null,
"videoable_id": 151,
"videoable_type": "Tv",
"created_at": "2014-09-02T11:13:40+05:00",
"video_source": null,
"video_source_cd": null
},
{
"id": 131,
"name": "",
"site": null,
"link": "",
"quality": null,
"video_type": null,
"videoable_id": 151,
"videoable_type": "Tv",
"created_at": "2014-09-02T11:13:40+05:00",
"video_source": null,
"video_source_cd": null
}
],
"seasons": []
},
{
"name": "Under the Dome",
"id": 160,
"videos": [],
"seasons": [
{
"name": "Season Specials",
"id": 267,
"videos": [],
"episodes": [
{
"name": "Inside Chester's Mill",
"id": 1112
}
]
}
]
}
]
First step is to move your logic to model, that way your controller will get more skinnier
in your Tv model
def self.all_with_seasons_and_episodes
tvs = includes(:videos, :seasons => [:videos, :episodes]).all
# loads all tvs and all its videos and seasons, seasons videos and episodes
tvs.map do |tv|
{
name: tv.name,
id: tv.id,
videos: tv.videos,
seasons: tv.map_seasons
}
end
end
private
def map_seasons
seasons.map do |s|
{
id: s.id,
name: s.name,
videos: s.videos,
episode: s.episodes.map {|e| {name: e.name, id: e.id} }
}
end
end
now you can use in like
def all_shows_with_videos
arr = Tv.all_with_seasons_and_episodes
#arr = Kaminari.paginate_array(arr).page(params[:page]).per(5)
respond_to do |format|
format.json {render :json => #arr}
end
end

Beautify JSON parsing with Hashie::Mash Rash?

Trying to parse some ugly JSON:
image = product.images.find { |i| i["sizeName"] == "Large" }
If I use Hashie::Mash Rash, can I make it look like this instead?
image = product.images.find { |i| i["size_name"] == "large" }
If so, why am I getting undefined method 'each_pair' for #<Array:0x007f84a0408540>? Please see https://gist.github.com/frankie-loves-jesus/6b8012f9197ca6c675a9 for a full example including a live app.
Example JSON:
{
"metadata": {
"category": {
"id": "women",
"name": "Women's Fashion"
},
"showSizeFilter": false,
"showColorFilter": true,
"offset": 0,
"limit": 20,
"total": 974184
},
"products": [
{
"id": 377083005,
"name": "BCBGeneration Women's Contrast Sleeve Trench",
"currency": "USD",
"price": 168,
"priceLabel": "$168.00",
"salePrice": 106.43,
"salePriceLabel": "$106.43",
"inStock": true,
"retailer": {
"id": "849",
"name": "Amazon.com",
"url": "http://www.shopstyle.com/browse/Amazon.com-US?pid=uid9616-726296-93"
},
"locale": "en_US",
"description": "This jacket features contrasting leather sleeves",
"brand": {
"id": "51",
"name": "BCBG MAX AZRIA",
"url": "http://www.shopstyle.com/browse/BCBG-MAX-AZRIA?pid=uid9616-726296-93"
},
"clickUrl": "http://api.shopstyle.com/action/apiVisitRetailer?id=377083005&pid=uid9616-726296-93",
"images": [
{
"sizeName": "Small",
"width": 32,
"height": 40,
"url": "http://resources.shopstyle.com/pim/7b/28/7b2894c203529b0956cdd6b760629d4a_small.jpg"
},
{
"sizeName": "Medium",
"width": 112,
"height": 140,
"url": "http://resources.shopstyle.com/pim/7b/28/7b2894c203529b0956cdd6b760629d4a_medium.jpg"
},
{
"sizeName": "Large",
"width": 164,
"height": 205,
"url": "http://resources.shopstyle.com/pim/7b/28/7b2894c203529b0956cdd6b760629d4a.jpg"
}
],
"colors": [
{
"name": "Chino"
}
],
"sizes": [
{
"name": "XX-Small"
},
{
"name": "X-Small"
}
],
"categories": [
{
"id": "raincoats-and-trenchcoats",
"name": "Raincoats & Trenchcoats"
}
]
}
]
}
This is my working code
require 'json'
require 'rash'
#json_text = <<END
{
"metadata": {
"category": {
"id": "women",
"name": "Women's Fashion"
},
"showSizeFilter": false,
"showColorFilter": true,
"offset": 0,
"limit": 20,
"total": 974184
},
"products": [
{
"id": 377083005,
"name": "BCBGeneration Women's Contrast Sleeve Trench",
"currency": "USD",
"price": 168,
"priceLabel": "$168.00",
"salePrice": 106.43,
"salePriceLabel": "$106.43",
"inStock": true,
"retailer": {
"id": "849",
"name": "Amazon.com",
"url": "http://www.shopstyle.com/browse/Amazon.com-US?pid=uid9616-726296-93"
},
"locale": "en_US",
"description": "This jacket features contrasting leather sleeves",
"brand": {
"id": "51",
"name": "BCBG MAX AZRIA",
"url": "http://www.shopstyle.com/browse/BCBG-MAX-AZRIA?pid=uid9616-726296-93"
},
"clickUrl": "http://api.shopstyle.com/action/apiVisitRetailer?id=377083005&pid=uid9616-726296-93",
"images": [
{
"sizeName": "Small",
"width": 32,
"height": 40,
"url": "http://resources.shopstyle.com/pim/7b/28/7b2894c203529b0956cdd6b760629d4a_small.jpg"
},
{
"sizeName": "Medium",
"width": 112,
"height": 140,
"url": "http://resources.shopstyle.com/pim/7b/28/7b2894c203529b0956cdd6b760629d4a_medium.jpg"
},
{
"sizeName": "Large",
"width": 164,
"height": 205,
"url": "http://resources.shopstyle.com/pim/7b/28/7b2894c203529b0956cdd6b760629d4a.jpg"
}
],
"colors": [
{
"name": "Chino"
}
],
"sizes": [
{
"name": "XX-Small"
},
{
"name": "X-Small"
}
],
"categories": [
{
"id": "raincoats-and-trenchcoats",
"name": "Raincoats & Trenchcoats"
}
]
}
]
}
END
hash = JSON.parse(#json_text)
#rash = Hashie::Rash.new( hash )
images = []
#rash.products.each do |product|
images << product.images.find { |i| i.size_name.downcase == "large" }
end
puts images.inspect
#[#<Hashie::Rash height=205 size_name="Large" url="http://resources.shopstyle.com/pim/7b/28/7b2894c203529b0956cdd6b760629d4a.jpg" width=164>]
It doesn't raise the error you have mentioned.
And I use
$ruby --version
ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin13.0.0]
gem list --local |grep 'rash'
rash (0.4.0)
$gem list --local |grep 'hashie'
hashie (3.2.0, 2.0.5)
Could you check yours?
And, if possible, dump the json at the moment that it raises the error.

Resources