Rails serialization of sibling objects into groups by name (active model serializers) - ruby-on-rails

I'm not sure the best way of approaching this; I've got a generic system for requesting data objects from an api and returning json by using ActiveModelSerializers and it's been fantasticly simple.
For one class I need to return data formatted differently than the normal class serilization and unsure of the best approach. No matter what it seems that I'm going to have to have an 'elsif' for this one class in the return (which pains me a little bit).
Currently I've got a class named 'curve' which a user has_many of, and so requesting a user's curve gets me something like this:
[{
"id": 7,
"name": "A",
"angle": 30,
"date": "2017-05-23T01:52:00.589-04:00",
"direction": "left",
"top": "C1",
"bottom": "C4",
"risser": 3,
"sanders": 8
}, {
"id": 8,
"name": "B",
"angle": 0,
"date": "2017-05-23T01:52:56.107-04:00",
"direction": "right",
"top": "C5",
"bottom": "C6",
"risser": null,
"sanders": null
}, {
"id": 9,
"name": "A",
"angle": 22,
"date": "2017-05-25T01:56:00.656-04:00",
"direction": "right",
"top": "C3",
"bottom": "C5",
"risser": null,
"sanders": null
}, {
"id": 11,
"name": "C",
"angle": 3,
"date": "2017-05-26T01:57:08.078-04:00",
"direction": "right",
"top": "C4",
"bottom": "C7",
"risser": null,
"sanders": null
}]
But I actually need each to be grouped by the name like so:
[{
"name": "A",
"points": [{
"id": 7,
"name": "A",
"angle": 30,
"date": "2017-05-23T01:52:00.589-04:00",
"direction": "left",
"top": "C1",
"bottom": "C4",
"risser": 3,
"sanders": 8
}, {
"id": 9,
"name": "A",
"angle": 22,
"date": "2017-05-25T01:56:00.656-04:00",
"direction": "right",
"top": "C3",
"bottom": "C5",
"risser": null,
"sanders": null
}]
},
{
"name": "B",
"points": [{
"id": 8,
"name": "B",
"angle": 0,
"date": "2017-05-23T01:52:56.107-04:00",
"direction": "right",
"top": "C5",
"bottom": "C6",
"risser": null,
"sanders": null
}]
},
{
"name": "C",
"points": [{
"id": 11,
"name": "C",
"angle": 3,
"date": "2017-05-26T01:57:08.078-04:00",
"direction": "right",
"top": "C4",
"bottom": "C7",
"risser": null,
"sanders": null
}]
}
]
Now I know I can do group_by and fiddle with the response - but even then it won't be using the default Curve serializer. I could also create a custom GroupedCurve serializer and possibly process each curve with a CurveSerializer - but at that point isn't it just like getting the default array and doing a map, and constructing my own hashes?
What's the best / cleanest way of processing data from top to the bottom format?
UPDATE:
Something like the following 'does the job' but the job is dirty:
def self.reformat_curves(curves)
arr = []
curves.each do |i|
alpha = i[:name]
entry = arr.find{|chunk| chunk[:name]==alpha}
if entry.nil?
arr << {name: alpha, points: [i]}
else
entry[:points] << i
end
end
return arr
end

Related

Is there a "fast" way to get info about variable Google Fonts?

I am building a UI as part of a product to make it easy to choose, select and style Google fonts. I am challenged by variable fonts because I cannot find a good way to get info about these.
The developer API provides metadata for all Google Fonts via a large JSON string. However, it does not seem to contain any data that would allow a developer to discern which fonts are variable. They all “appear” to be standard fonts.
Is there a fast way to get such data? By fast, I am talking about something similar to Google Font’s developer API, but with data for the various variable fonts that would include:
Which fonts are variable?
Which axes do the variable fonts ship with?
Currently, the only recommended approach I’ve seen for exploring variable fonts and their axes is to load the fonts into a web page and use Firefox’s Font editor in the developer tools to manually get the data. But with the current 112 variable fonts in Google Fonts, it could take days to collect this info. So my question is:
Is there a faster way to get meta data for the variable fonts in Google Fonts?
I am working on a font picker plugin and I ran into a similar problem, so I started investigating the google fonts main distribution site until I found what I was looking for.
Google's fonts site executes a call to the following API endpoint.
https://fonts.google.com/metadata/fonts
Which returns the following text file.
)]}'{"axisRegistry": [
{
"tag": "FILL",
"displayName": "Fill",
"min": 0.0,
"defaultValue": 0.0,
"max": 1.0,
"precision": -2,
"description": "The Fill axis is intended to provide a treatment of the design that fills in transparent forms with opaque ones (and sometimes interior opaque forms become transparent, to maintain contrasting shapes). Transitions often occur from the center, a side, or a corner, but can be in any direction. This can be useful in animation or interaction to convey a state transition. The numbers indicate proportion filled, from 0 (no treatment) to 1 (completely filled).",
"fallbacks": [
{
"name": "Normal",
"value": 0.0
},
{
"name": "Filled",
"value": 1.0
}
]
} ...],"familyMetadataList": [{
"family": "Alegreya",
"displayName": null,
"category": "Serif",
"size": 425570,
"subsets": [
"menu",
"cyrillic",
"cyrillic-ext",
"greek",
"greek-ext",
"latin",
"latin-ext",
"vietnamese"
],
"fonts": {
"400": {
"thickness": 4,
"slant": 1,
"width": 6,
"lineHeight": 1.361
},
"400i": {
"thickness": 4,
"slant": 4,
"width": 6,
"lineHeight": 1.361
},
"500": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"500i": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"600": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"600i": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"700": {
"thickness": 7,
"slant": 1,
"width": 7,
"lineHeight": 1.361
},
"700i": {
"thickness": 6,
"slant": 4,
"width": 6,
"lineHeight": 1.361
},
"800": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"800i": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"900": {
"thickness": 8,
"slant": 1,
"width": 7,
"lineHeight": 1.361
},
"900i": {
"thickness": 8,
"slant": 4,
"width": 6,
"lineHeight": 1.361
}
},
"axes": [
{
"tag": "wght",
"min": 400.0,
"max": 900.0,
"defaultValue": 400.0
}
],
"unsupportedAxes": [],
"designers": [
"Juan Pablo del Peral",
"Huerta Tipográfica"
],
"lastModified": "2021-02-11",
"dateAdded": "2011-12-19",
"popularity": 159,
"trending": 828,
"defaultSort": 164,
"androidFragment": null,
"isNoto": false
}...],...}
Please note that while the above looks like a JSON file, it will be treated as a text file, so you will have to remove this part )]}' from the top of the text file, so you can then parse it as a JSON file.
The only top-level property that matters (as far as your use case is concerned) is the "familyMetadataList" property, as the name implies it includes all the fonts metadata, which includes the axes any given font has.
You will have to loop on the "familyMetadataList" prop and see if the font's axes member has an array that is not empty, from there we can deduce that it is a variable font.
You can do something as simple as this to figure out which font is variable.
const variableFonts=[];
const googleFontJSON = {
"familyMetadataList": [
{
"family": "Alegreya",
"displayName": null,
"category": "Serif",
"size": 425570,
"subsets": [
"menu",
"cyrillic",
"cyrillic-ext",
"greek",
"greek-ext",
"latin",
"latin-ext",
"vietnamese"
],
"fonts": {
"400": {
"thickness": 4,
"slant": 1,
"width": 6,
"lineHeight": 1.361
},
"400i": {
"thickness": 4,
"slant": 4,
"width": 6,
"lineHeight": 1.361
},
"500": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"500i": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"600": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"600i": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"700": {
"thickness": 7,
"slant": 1,
"width": 7,
"lineHeight": 1.361
},
"700i": {
"thickness": 6,
"slant": 4,
"width": 6,
"lineHeight": 1.361
},
"800": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"800i": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"900": {
"thickness": 8,
"slant": 1,
"width": 7,
"lineHeight": 1.361
},
"900i": {
"thickness": 8,
"slant": 4,
"width": 6,
"lineHeight": 1.361
}
},
"axes": [
{
"tag": "wght",
"min": 400.0,
"max": 900.0,
"defaultValue": 400.0
}
],
"unsupportedAxes": [],
"designers": [
"Juan Pablo del Peral",
"Huerta Tipográfica"
],
"lastModified": "2021-02-11",
"dateAdded": "2011-12-19",
"popularity": 159,
"trending": 828,
"defaultSort": 164,
"androidFragment": null,
"isNoto": false
},
{
"family": "Alegreya SC",
"displayName": null,
"category": "Serif",
"size": 381295,
"subsets": [
"menu",
"cyrillic",
"cyrillic-ext",
"greek",
"greek-ext",
"latin",
"latin-ext",
"vietnamese"
],
"fonts": {
"400": {
"thickness": 4,
"slant": 1,
"width": 7,
"lineHeight": 1.361
},
"400i": {
"thickness": 4,
"slant": 4,
"width": 7,
"lineHeight": 1.361
},
"500": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"500i": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"700": {
"thickness": 6,
"slant": 1,
"width": 7,
"lineHeight": 1.361
},
"700i": {
"thickness": 6,
"slant": 3,
"width": 7,
"lineHeight": 1.361
},
"800": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"800i": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"900": {
"thickness": 8,
"slant": 1,
"width": 7,
"lineHeight": 1.361
},
"900i": {
"thickness": 8,
"slant": 3,
"width": 7,
"lineHeight": 1.361
}
},
"axes": [],
"unsupportedAxes": [],
"designers": [
"Juan Pablo del Peral",
"Huerta Tipográfica"
],
"lastModified": "2021-03-24",
"dateAdded": "2011-12-19",
"popularity": 436,
"trending": 249,
"defaultSort": 443,
"androidFragment": null,
"isNoto": false
}
]}; // The array of font meta data
googleFontJSON.familyMetadataList.forEach(font => {
if (font.axes.length) {
font.isVariable=true;
} else {
font.isVariable=false;
}
});
console.log(googleFontJSON);
How you analyze the data is of course entirely your own prerogative.
Good luck with your project, Mr.Steven.
You can also acquire more information about any given variable font's axes step through the axis registry prop found JSON file found at https://fonts.google.com/metadata/fonts.
Simply examine the precision prop.
For example, axes with a 0.1 step like "opsz" and "wdth" have their precision set to -1, axes with a 0.01 step like "CASL" and "MONO" have their precision set to -2.
"axisRegistry": [
{
"tag": "opsz",
"displayName": "Optical size",
"min": 6.0,
"defaultValue": 14.0,
"max": 144.0,
"precision": -1, //<=== Here
"description": "Adapt the ...",
"fallbacks": [
{
"name": "6pt",
"value": 6.0
},
{
"name": "7pt",
"value": 7.0
}...
]
},...
I love the answer from Stranger1586. But I really also need data on the steps for each axis in order to properly build UI elements such as sliders. So I decided to write a scraper to scrape the data from https://fonts.google.com/variablefonts. That page contains updated data on all variable fonts and all supported axes according to Google Font's GitHub page.
The scraper creates a JSON file with axes data for each font family. I hope it might be helpful to others having the same need. Here is the code:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.firefox.options import Options
from bs4 import BeautifulSoup
import json
def get_variable_fonts_data():
print('Opening: Google Variable Fonts page...')
options = Options()
options.headless = True
gecko_path = r'D:\Anaconda3\envs\py37\Lib\site-packages\helium\_impl\webdrivers\windows\geckodriver.exe'
url = 'https://fonts.google.com/variablefonts'
browser = webdriver.Firefox(options=options, executable_path=gecko_path)
browser.get(url)
timeout = 10 # seconds
# Wait for the table element as it is not part of the page source but is generated with JavaScript
try:
WebDriverWait(browser, timeout).until(EC.presence_of_element_located((By.TAG_NAME, 'table')))
print('Generating font table')
except TimeoutException:
print("Loading took too much time!")
soup = BeautifulSoup(browser.page_source, 'html.parser')
table = soup.find('table')
table_head = table.find('thead').find('tr')
header_values = []
for cell in table_head.find_all('th'):
header_values.append(cell.encode_contents().decode("utf-8").strip())
table_body = table.find('tbody')
variable_fonts_data = {}
for row in table_body.find_all('tr'):
axis_data = {}
cells = row.find_all('td')
font_family_name = cells[0].find('a').encode_contents().decode("utf-8").strip()
if not (font_family_name in variable_fonts_data):
variable_fonts_data[font_family_name] = {'Axes': {}}
axis_data[header_values[2]] = cells[2].encode_contents().decode("utf-8").strip() # Default
axis_data[header_values[3]] = cells[3].encode_contents().decode("utf-8").strip() # Min
axis_data[header_values[4]] = cells[4].encode_contents().decode("utf-8").strip() # Max
axis_data[header_values[5]] = cells[5].encode_contents().decode("utf-8").strip() # Step
variable_fonts_data[font_family_name]['Axes'][cells[1].encode_contents().decode("utf-8").strip()] = axis_data
return variable_fonts_data
with open('google_variable_fonts.json', 'w') as fonts_file:
json.dump(get_variable_fonts_data(), fonts_file)

Shopify products/delete webhook only returns ID

My ruby on rails app is supposed to do some things whenever a product is deleted. According to Shopify's website here the response to products/delete is supposed to be a JSON object with information such as the product_id associated with the product that was deleted:
{
"id": 788032119674292922,
"title": "Example T-Shirt",
"body_html": null,
"vendor": "Acme",
"product_type": "Shirts",
"created_at": null,
"handle": "example-t-shirt",
"updated_at": "2021-07-01T14:08:43-04:00",
"published_at": "2021-07-01T14:08:43-04:00",
"template_suffix": null,
"published_scope": "web",
"tags": "example, mens, t-shirt",
"admin_graphql_api_id": "gid:\/\/shopify\/Product\/788032119674292922",
"variants": [
{
"id": 642667041472713922,
"product_id": 788032119674292922,
"title": "",
"price": "19.99",
"sku": "example-shirt-s",
"position": 0,
"inventory_policy": "deny",
"compare_at_price": "24.99",
"fulfillment_service": "manual",
"inventory_management": "shopify",
"option1": "Small",
"option2": null,
"option3": null,
"created_at": null,
"updated_at": null,
"taxable": true,
"barcode": null,
"grams": 200,
"image_id": null,
"weight": 200.0,
"weight_unit": "g",
"inventory_item_id": null,
"inventory_quantity": 75,
"old_inventory_quantity": 75,
"requires_shipping": true,
"admin_graphql_api_id": "gid:\/\/shopify\/ProductVariant\/642667041472713922"
},
{
"id": 757650484644203962,
"product_id": 788032119674292922,
"title": "",
"price": "19.99",
"sku": "example-shirt-m",
"position": 0,
"inventory_policy": "deny",
"compare_at_price": "24.99",
"fulfillment_service": "manual",
"inventory_management": "shopify",
"option1": "Medium",
"option2": null,
"option3": null,
"created_at": null,
"updated_at": null,
"taxable": true,
"barcode": null,
"grams": 200,
"image_id": null,
"weight": 200.0,
"weight_unit": "g",
"inventory_item_id": null,
"inventory_quantity": 50,
"old_inventory_quantity": 50,
"requires_shipping": true,
"admin_graphql_api_id": "gid:\/\/shopify\/ProductVariant\/757650484644203962"
}
],
"options": [
{
"id": 527050010214937811,
"product_id": 788032119674292922,
"name": "Title",
"position": 1,
"values": [
"Small",
"Medium"
]
}
],
"images": [
{
"id": 539438707724640965,
"product_id": 788032119674292922,
"position": 0,
"created_at": null,
"updated_at": null,
"alt": null,
"width": 323,
"height": 434,
"src": "\/\/cdn.shopify.com\/shopifycloud\/shopify\/assets\/shopify_shirt-39bb555874ecaeed0a1170417d58bbcf792f7ceb56acfe758384f788710ba635.png",
"variant_ids": [
],
"admin_graphql_api_id": "gid:\/\/shopify\/ProductImage\/539438707724640965"
}
],
"image": null
}
However, whenever I go to test it by actually deleting a product in the Shopify Admin interface, I'm only getting the id in my response. Anybody know why this is happening? My setup for the other webhooks is the exact same and I'm not having any other issues.
Seems like this is an open issue on the shopify_api gem for version 2021-01. I don't think you are doing anything wrong. It looks like nobody has responded in a while to the issue, you might want to try to upgrade to another version to see if they fixed it in any of the newer versions.
EDIT: According to a post from 3/2017 the expected behaviour from deleted endpoints is to only return the ID of the resource that was deleted. This could be why the issue on Github is being ignored.

Swift 4 - How to structure a json object and using decodable in switch (not working)

I'm trying to create a structure for the following json object using swift decodable.
{
"template": [
{
"id": 8,
"question": "Favorite Color?",
"category": "Color",
"section": "Favorite Colors",
"is_active": 1,
},
[
{
"id": 14,
"question_id": 8,
"option_name": "Red",
"is_active": 1,
},
{
"id": 16,
"question_id": 8,
"option_name": "Orange",
"is_active": 1,
}
],
{
"id": 9,
"question": "What cars do you drive?",
"category": "Cars",
"section": "Favorite Cars",
"is_active": 1,
},
[
{
"id": 15,
"question_id": 9,
"option_name": "Toyota",
"is_active": 1,
},
{
"id": 18,
"question_id": 9,
"option_name": "Honda",
"is_active": 1,
},
{
"id": 19,
"question_id": 9,
"option_name": "BMW",
"is_active": 1,
}
]
]
}
I have some like:
public struct GameTemplate:Decodable {
question:String?
}
public struct Game:Decodable {
let template[GameTemplate]
}
For some reason when i tried to parse it doesn't work i get an error stating that struct is not a dictionary. I have tried casting the struct value but that didn't work either at this point just need to get a nice and clean json object after is decoded.
your JSON format is not consistent.
Just take the first category of color :
{
"template": [
{
"id": 8,
"question": "Favorite Color?",
"category": "Color",
"section": "Favorite Colors",
"is_active": 1,
},
[
{
"id": 14,
"question_id": 8,
"option_name": "Red",
"is_active": 1,
},
{
"id": 16,
"question_id": 8,
"option_name": "Orange",
"is_active": 1,
}
],
]
}
The template is an array having dictionary on 0 index and array on 1 index.
It is decodable in a different way but that's an extra effort.
If possible make the JSON data consistent and club categories in one index of array as :
{
"template": [
{
"id": 8,
"question": "Favorite Color?",
"category": "Color",
"section": "Favorite Colors",
"is_active": 1,
"subCategory": [
{
"id": 14,
"question_id": 8,
"option_name": "Red",
"is_active": 1,
},
{
"id": 16,
"question_id": 8,
"option_name": "Orange",
"is_active": 1,
}
]
}
]
}
and the same way club the different category of cars.
It will be easy for you to decode as:
public struct GameTemplate:Decodable {
question: String?
subCategory: [SubCategory]
}
public struct SubCategory:Decodable {
option_name: String?
}
public struct Game:Decodable {
let template: [GameTemplate]
}
Hope you get it what I am trying to explain.

Avro java serialization as json not working correctly

I have a simple avro schema, from which I generated a java class using the avro-maven-plugin.
The avro schema is as follows:
{
"type": "record",
"name": "addressGeo",
"namespace": "com.mycompany",
"doc": "Best record address and list of geos",
"fields": [
{
"name": "version",
"type": "int",
"default": 1,
"doc": "version the class"
},
{
"name": "eventType",
"type": "string",
"default": "addressGeo",
"doc": "event type"
},
{
"name": "parcelId",
"type": "long",
"doc": "ParcelID of the parcel. Join parcelid and sequence with ParcelInfo"
},
{
"name": "geoCodes",
"type": {"type": "array", "items": "com.mycompany.geoCode"},
"doc": "Multiple Geocodes, with restrictions information"
},
{
"name": "brfAddress",
"type": ["null", "com.mycompany.address"],
"doc": "Address cleansed version of BRF"
}
]
}
If I construct a simple object using the builder, and serialize it using json, I get the following output:
{
"version": 1,
"eventType": {
"bytes": [
97,
100,
100,
114,
101,
115,
115,
71,
101,
111
],
"length": 10,
"string": null
},
"parcelId": 1,
"geoCodes": [
{
"version": 1,
"latitude": 1,
"longitude": 1,
"geoQualityCode": "g",
"geoSourceTypeID": 1,
"restrictions": "NONE"
}
],
"brfAddress": {
"version": 1,
"houseNumber": "1",
"houseNumberFraction": null,
"streetDirectionPrefix": null,
"streetName": "main",
"streetSuffix": "street",
"streetDirectionSuffix": null,
"fullStreetAddress": "1 main street, seattle, wa, 98101",
"unitPrefix": null,
"unitNumber": null,
"city": "seattle",
"state": "wa",
"zipCode": "98101",
"zipPlusFour": null,
"addressDPV": "Y",
"addressQualityCode": "good",
"buildingNumber": "1",
"carrierRoute": "t",
"censusTract": "c",
"censusTractAndBlock": "b",
"dataCleanerTypeID": 1,
"restrictions": "NONE"
}
}
Note the output of the eventType field. It is coming through as an array of bytes whereas the type of the field is a CharSequence.
Any idea why serialization is doing this? It works fine for other types that are strings.
I am using google-gson to serialize the object to json.
You might be working with a older version of avro, that uses CharSequence. Ideally string type should be java String type. I would suggest to update the avro version or have a look at this one - Apache Avro: map uses CharSequence as key

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

Resources