Can't map JSON data to model - ruby-on-rails

Currently trying to call an API and map an attribute to my model. e.g. image_src string from the JSON response to image string in my model. But right now It's getting the error 'no implicit conversion of String into Integer'.
Feed.rb
require 'httparty'
require 'json'
class Feed < ActiveRecord::Base
include HTTParty
base_uri 'https://extraction.import.io/query/runtime'
has_many :entries
# GET /feeds
# GET /feeds.json
def fetch_data
response = self.class.get("/2365205f-8502-439e-a6d2-73988cfa03f1?&url=http%3A%2F%2F%2F")
#elements = response.parsed_response["extractorData"]
#elements.map do |image_info|
self.entries.create(image: image_info['url'])
end
end
end
Entry.rb
class Entry < ActiveRecord::Base
belongs_to :feed
end
HTML
<% #feed.entries.each do |image| %>
<div class="grid-item">
<%= image_tag(image) %>
</div>
<% end %>
JSON Response
{
"extractorData": {
"url": "http://linxspiration.com/",
"resourceId": "e26012fd5f25602c1c4e0945a7507e1f",
"data": [
{
"group": [
{
"image": [
{
"src": "http://40.media.tumblr.com/0a38dd25a41e0702940c084b60bee860/tumblr_o5c0tyGhOP1qkegsbo1_1280.jpg",
"href": "http://linxspiration.com/post/142509606341"
}
]
},
{
"image": [
{
"src": "http://36.media.tumblr.com/276def9e46bdfb9efee7f7d4e4444195/tumblr_o5c0szx4F21qkegsbo1_1280.jpg",
"href": "http://linxspiration.com/post/142506402604"
}
]
},
{
"image": [
{
"src": "http://40.media.tumblr.com/4953cdecc24389d94844dfb88c819d8c/tumblr_o055uh8b7h1uhpqwfo1_1280.jpg",
"href": "http://linxspiration.com/post/142503176501/linxsupply-discipline-gets-shit-done-buy-this"
}
]
},
{
"image": [
{
"src": "http://41.media.tumblr.com/353f10283fc3a0237262629b6a395c90/tumblr_o5aadrw6l31qkegsbo1_1280.jpg",
"href": "http://linxspiration.com/post/142499072059"
}
]
},
{
"image": [
{
"src": "http://40.media.tumblr.com/889c65a662a1b690f299593e3581b947/tumblr_o57uysuSjF1tq9q5vo1_1280.jpg",
"href": "http://linxspiration.com/post/142493659142/blazepress-sunrise-in-venice"
}
]
},
{
"image": [
{
"src": "http://45.media.tumblr.com/14c24e549a6559b48933f05ff40e3627/tumblr_o57vmsJ7gk1tq9q5vo1_400.gif",
"href": "http://linxspiration.com/post/142488060049/blazepress-i-lick-paw"
}
]
},
{
"image": [
{
"src": "http://36.media.tumblr.com/f184f397d14563c9e41136c5fe370016/tumblr_o59oo0pUy61qkegsbo1_1280.jpg",
"href": "http://linxspiration.com/post/142476686818"
}
]
},
{
"image": [
{
"src": "http://40.media.tumblr.com/453b70fd4055952e907766a5942cc560/tumblr_o59ohsGHBo1qkegsbo1_1280.jpg",
"href": "http://linxspiration.com/post/142470776914"
}
]
},
{
"image": [
{
"src": "http://41.media.tumblr.com/1de6c873de55ddb899f83441454ff5bb/tumblr_o59ohhnd0k1qkegsbo1_1280.jpg",
"href": "http://linxspiration.com/post/142465333421"
}
]
},
{
"image": [
{
"src": "http://40.media.tumblr.com/f71b3ee53f51a9679dc65096933f2b08/tumblr_o59of8kouq1qkegsbo1_1280.jpg",
"href": "http://linxspiration.com/post/142456009994"
}
]
},
{
"image": [
{
"src": "http://40.media.tumblr.com/b6aa0dc78619a6b9e09b232224c0bfb7/tumblr_o59oeu18Ly1qkegsbo1_1280.jpg",
"href": "http://linxspiration.com/post/142452801623"
}
]
},
{
"image": [
{
"src": "http://41.media.tumblr.com/d1c5a23af31880d10fd89fc8a6a0b8e6/tumblr_o585z3mPuF1tq9q5vo1_1280.jpg",
"href": "http://linxspiration.com/post/142449893982/blazepress-life"
}
]
},
{
"image": [
{
"src": "http://41.media.tumblr.com/03369de74399e12e1901b3751917c512/tumblr_o54gbfJlXx1qkegsbo1_1280.jpg",
"href": "http://linxspiration.com/post/142445969058"
}
]
},
{
"image": [
{
"src": "http://40.media.tumblr.com/6543cbb31ea206a59cbdd1e865d63562/tumblr_o54mncUOEP1qkegsbo1_1280.jpg",
"href": "http://linxspiration.com/post/142440337822"
}
]
}
]
}
]
},
"pageData": {
"statusCode": 200,
"timestamp": 1460206655245
}
}
Any help would be brilliant!

response = self.class.get("/2365205f-8502-439e-a6d2-73988cfa03f1?&url=http%3A%2F%2F%2F")
puts response.parsed_response
Shows that the auth is failing:
<html>
<head><title>401 Authorization Required</title></head>
<body bgcolor="white">
<center><h1>401 Authorization Required</h1></center>
<hr><center>openresty/1.9.7.3</center>
</body>
</html>
def fetch_data
...
#elements = response.parsed_response["extractorData"]
# To access the image src's:
image_srcs = #elements['data'].first['group'].map{ | z | z['image'].first['src']}
image_srcs.each do |src|
self.entries.create(image: src)
end
end

Related

AWS API Gateway api key required not set to 'true' after deployment

I have a .NET solution that uses a SAM template to generate cloudformation to deploy the stack. I am expecting the deployment - once complete - to have API Key Required = true on at least one of the methods. However after deployment, the keys and usage plans are created, but in the console the api key required is still set to false?
See below:
My SAM template:
"ServerlessRestApi": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Description":"This is a placeholder for the description of this web api",
"Body": {
"info": {
"version": "1.0",
"title": {
"Ref": "AWS::StackName"
}
},
"x-amazon-apigateway-api-key-source": "HEADER",
"paths": {
"datagw/general/table/get/{tableid}": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableResponse.Arn}/invocations"
}
},
"responses": {}
},
"security":[
{
"api_key":[]
}
]},
"securityDefinitions":{
"api_key":{
"type":"apiKey",
"name":"x-api-key",
"in":"header"
}
},
"/": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Get.Arn}/invocations"
}
},
"responses": {}
}
},
"/tables/{tableid}/{columnid}": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableBasic.Arn}/invocations"
}
},
"responses": {}
}
}
},
"swagger": "2.0"
}
}
},
I am not that familiar with swagger definitions, I know only the basics of SAM and CloudFormation. What am I missing here? I have reviewed other answers on stack overflow and believe I've copied the configuration correctly.
When I check the generated CloudFormation, my entries regarding x-api-key are not even present in the template?
"ServerlessRestApi": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Body": {
"info": {
"version": "1.0",
"title": {
"Ref": "AWS::StackName"
}
},
"paths": {
"datagw/general/table/get/{tableid}": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableResponse.Arn}/invocations"
}
},
"responses": {}
}
},
"/datagw/general/webhook/ccnotify": {
"post": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PostClickCollectNotification.Arn}/invocations"
}
},
"responses": {}
}
},
"/": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Get.Arn}/invocations"
}
},
"responses": {}
}
},
"/tables/{tableid}/{columnid}": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableBasic.Arn}/invocations"
}
},
"responses": {}
}
},
"/datagw/general/post/sohupdate": {
"post": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PostClickCollectStockUpdate.Arn}/invocations"
}
},
"responses": {}
}
}
},
"swagger": "2.0"
}
}
},
EDIT: This is what I have worked up to, but still API key required is not set to true in the API once the deployment has completed.
"ServerlessRestApi": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Description":"InSite Web API Version 2.0.0.0",
"Body": {
"swagger": "2.0",
"info": {
"version": "1.0",
"title": {
"Ref": "AWS::StackName"
}
},
"x-amazon-apigateway-api-key-source" : "HEADER",
"schemes":["https"],
"paths": {
"tables/query/{tableid}": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "GET",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableResponse.Arn}/invocations"
}
},
"responses": {},
"security": [
{
"api_key": []
}
]
}
},
"/products/update/": {
"post": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PostClickCollectStockUpdate.Arn}/invocations"
}
},
"responses": {}
}
},
"/": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "GET",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Get.Arn}/invocations"
}
},
"responses": {}
}
},
"/tables/{tableid}/{columnid}": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "GET",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableBasic.Arn}/invocations"
}
},
"responses": {}
}
}
},
"securityDefinitions": {
"api_key": {
"type": "apiKey",
"name": "x-api-key",
"in": "header"
}
}
}
}
},
So first off, if you are using the SAM framework, then why not try the serverless API (AWS::Serverless::Api) which has an Auth object where you can turn on ApiKeyRequired.
https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessapi
"ServerlessRestApi": {
"Type": "AWS::Serverless::Api",
"Properties": {
"Description":"InSite Web API Version 2.0.0.0",
"Auth": {
"ApiKeyRequired": "true"
},
"DefinitionBody": {
"swagger": "2.0",
"info": {
"version": "1.0",
"title": {
"Ref": "AWS::StackName"
}
},
"x-amazon-apigateway-api-key-source" : "HEADER",
"schemes":["https"],
"paths": {
"tables/query/{tableid}": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "GET",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableResponse.Arn}/invocations"
}
},
"responses": {},
"security": [
{
"api_key": []
}
]
}
},
"/products/update/": {
"post": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PostClickCollectStockUpdate.Arn}/invocations"
}
},
"responses": {}
}
},
"/": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "GET",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Get.Arn}/invocations"
}
},
"responses": {}
}
},
"/tables/{tableid}/{columnid}": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "GET",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableBasic.Arn}/invocations"
}
},
"responses": {}
}
}
},
"securityDefinitions": {
"api_key": {
"type": "apiKey",
"name": "x-api-key",
"in": "header"
}
}
}
}
},
If for some reason you cannot use the serverless, you might be trying to overload the RestApi (which is fine, but you lose some of the other fine grain options). For full disclosure I do not work with API gateway in this way (I use the serverless transform) so this is all from reading the documentation and not from experiance.
I would try creating a bare bones AWS::ApiGateway::RestApi and then attach an AWS::ApiGateway::Method to the RestApi by reference it though RestApiId.
[1] https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-method.html
I think you are missing the "securityDefinitions":
Body:
swagger: "2.0"
...
...
securityDefinitions:
sigv4:
type: "apiKey"
name: "x-api-key"
in: "header"
x-amazon-apigateway-authorizer:
type: token
You can find here some more examples:
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-as-s3-proxy-export-swagger-with-extensions.html

Removing empty hashes {} from array in Active Model Serialized object

I have a few conditions where don't want to serialize the current object and want to skip it. But i haven't found a way to do that so I am ignoring attributes on attribute :foo, if: :condition. And this is generating empty {} in my serialized object inside arrays. How do I fix this?
[
{
"id": 392027,
"name": "ISC Board",
"grades":[
{
"id": 333938,
"name": "1",
"subjects": [
{
"id": 571671,
"subject": "Math"
},
{
"id": 742980,
"subject": "Science"
},
{
"id": 186926,
"subject": "English"
},
{
"id": 658224,
"subject": "Social_Studies"
},
{},
{},
{}
]
},
{
"id": 333943,
"name": "2",
"subjects": [
{
"id": 571671,
"subject": "Math"
},
{
"id": 742980,
"subject": "Science"
},
{
"id": 186926,
"subject": "English"
},
{
"id": 658224,
"subject": "Social_Studies"
},
{},
{},
{}
]
},
]
},
{
"id": 666627,
"name": "NY Board",
"grades":[
{
"id": 333938,
"name": "1",
"subjects": [
{
"id": 571671,
"subject": "Math"
},
{
"id": 742980,
"subject": "Science"
},
{
"id": 186926,
"subject": "English"
},
{
"id": 658224,
"subject": "Social_Studies"
},
{},
{},
{}
]
},
{
"id": 432943,
"name": "2",
"subjects": [
{
"id": 571671,
"subject": "Math"
},
{
"id": 742980,
"subject": "Science"
},
{
"id": 186926,
"subject": "English"
},
{
"id": 658224,
"subject": "Social_Studies"
},
{},
{},
{}
]
},
]
}
]
serializer looks something like this-
class BoardSerializer < ActiveModel::Serializer
#some code
class GradeSerializer < ActiveModel::Serializer
has_many :subjects
#some code
class SubjectSerializer < ActiveModel::Serializer
attribute :id, if: :condition
attribute :name, key: :subject, if: :condition
def condition
#some code
#returns true or false
#will not return both :id and :subject if false- I want to
#skip this current object if condition fails. (returns {})
end
end
end
end
How do I simply skip the current object in the serializer or remove empty hashes? Thanks
Please, check if this is the expected result:
input.transform_values { |v| v.map {|e| e.transform_values { |vv| vv.class == Array ? vv.select { |ee| ee unless ee.empty? } : vv } } }
# => {:grades=>[{:id=>333938, :name=>"1", :subjects=>[{:id=>571671, :subject=>"Math"}, {:id=>742980, :subject=>"Science"}, {:id=>186926, :subject=>"English"}, {:id=>658224, :subject=>"Social_Studies"}]}]}
EDIT: to meet changes in OP question.
input.map { |e| e.transform_values { |v| v.is_a?(Array) ? v.map {|ee| ee.transform_values { |vv| vv.is_a?(Array) ? vv.select { |eee| eee unless eee.empty? } : vv } } : v } }
# => [{:id=>392027, :name=>"ISC Board", :grades=>[{:id=>333938, :name=>"1", :subjects=>[{:id=>571671, :subject=>"Math"}, {:id=>742980, :subject=>"Science"}, {:id=>186926, :subject=>"English"}, {:id=>658224, :subject=>"Social_Studies"}]}, {:id=>333943, :name=>"2", :subjects=>[{:id=>571671, :subject=>"Math"}, {:id=>742980, :subject=>"Science"}, {:id=>186926, :subject=>"English"}, {:id=>658224, :subject=>"Social_Studies"}]}]}, {:id=>666627, :name=>"NY Board", :grades=>[{:id=>333938, :name=>"1", :subjects=>[{:id=>571671, :subject=>"Math"}, {:id=>742980, :subject=>"Science"}, {:id=>186926, :subject=>"English"}, {:id=>658224, :subject=>"Social_Studies"}]}, {:id=>432943, :name=>"2", :subjects=>[{:id=>571671, :subject=>"Math"}, {:id=>742980, :subject=>"Science"}, {:id=>186926, :subject=>"English"}, {:id=>658224, :subject=>"Social_Studies"}]}]}]
You can use #select! for this matter:
input = {
"grades":
[
{
"id": 333938,
"name": "1",
"subjects":
[
{
"id": 571671,
"subject": "Math"
},
{
"id": 742980,
"subject": "Science"
},
{
"id": 186926,
"subject": "English"
},
{
"id": 658224,
"subject": "Social_Studies"
},
{},
{},
{}
]
}
]
}
input[:grades].first[:subjects].select! { |i| !i.empty? }

How to read geojson with vega

It sounds super simple, but I can't get how can I use geojson, not topojson, for my polygons.
that's my current attempt:
"data": [
{
"name": "nabs",
"url": "both_boundaries.geojson",
"format": {"type": "json"},
"transform": [
{
"type": "geopath", "projection": "mercator",
"scale": 74, "center": [-73.99,40.72]
}
]
}
]
You have to parse the features using property within your format:
"format": {"type": "json", "property":"features"},
Full example spec:
{"$schema": "https://vega.github.io/schema/vega/v3.0.json",
"width": 500,
"height": 600,
"autosize": "none",
"signals": [
{
"name": "translate0",
"update": "width / 2"
},
{
"name": "translate1",
"update": "height / 2"
}
],
"projections": [
{
"name": "projection",
"size": {"signal": "[width, height]"},
"fit": {"signal": "data('netherlands')"}
}
],
"data": [
{
"name": "netherlands",
"url": "https://raw.githubusercontent.com/mattijn/datasets/master/NL_outline_geo.json",
"format": {
"type": "json",
"property": "features"
}
}
],
"marks": [
{
"type": "shape",
"from": {
"data": "netherlands"
},
"encode": {
"update": {
"strokeWidth": {
"value": 0.5
},
"stroke": {
"value": "darkblue"
},
"fill": {
"value": "lightblue"
},
"fillOpacity": {
"value": 0.5
}
},
"hover": {
"fill": {
"value": "#66C2A5"
},
"strokeWidth": {
"value": 2
},
"stroke": {
"value": "#FC8D62"
}
}
},
"transform": [
{
"type": "geoshape",
"projection": "projection"
}
]
}
]
}

Removing links using JasonApi Resources Gem

I have a simple model with the following classes:
class Country < ApplicationRecord
has_many :country_categories
has_many :categories, through: :country_categories
end
class CountryCategory < ApplicationRecord
belongs_to :country
belongs_to :category
end
class Category < ApplicationRecord
has_many :country_categories
has_many :countries, through: :country_categories
end
and the resources:
class CountryResource < JSONAPI::Resource
has_many :country_categories
end
When I do a GETrequest to /countries/1?include=country_categories.category the response always brings a lot of links. For example
{
"data": {
"id": "31",
"type": "countries",
"attributes": {
"description": null
},
"relationships": {
"country-categories": {
"links": {
"self": "http://api.localhost.local:3000/api/v1/countries/31/relationships/country-categories",
"related": "http://api.localhost.local:3000/api/v1/countries/31/country-categories"
},
"data": [
{
"type": "country-categories",
"id": "129"
},
{
"type": "country-categories",
"id": "130"
}
]
},
}
},
"included": [
{
"id": "129",
"type": "country-categories",
"attributes": {
"stuff": "aaa"
},
"relationships": {
"country-subcategories": {
"links": {
"self": "http://api.localhost.local:3000/api/v1/country-categories/129/relationships/country-subcategories",
"related": "http://api.localhost.local:3000/api/v1/country-categories/129/country-subcategories"
}
},
"category": {
"links": {
"self": "http://api.localhost.local:3000/api/v1/country-categories/129/relationships/category",
"related": "http://api.localhost.local:3000/api/v1/country-categories/129/category"
},
"data": {
"type": "categories",
"id": "1"
}
}
}
},
{
"id": "130",
"type": "country-categories",
"attributes": {
"stuff": "sfasf"
},
"relationships": {
"country-subcategories": {
"links": {
"self": "http://api.localhost.local:3000/api/v1/country-categories/130/relationships/country-subcategories",
"related": "http://api.localhost.local:3000/api/v1/country-categories/130/country-subcategories"
}
},
"category": {
"links": {
"self": "http://api.localhost.local:3000/api/v1/country-categories/130/relationships/category",
"related": "http://api.localhost.local:3000/api/v1/country-categories/130/category"
},
"data": {
"type": "categories",
"id": "3"
}
}
}
},
{
"id": "1",
"type": "categories",
"links": {
"self": "http://api.localhost.local:3000/api/v1/categories/1"
},
"attributes": {
"name": "Value extraction"
},
"relationships": {
"subcategories": {
"links": {
"self": "http://api.localhost.local:3000/api/v1/categories/1/relationships/subcategories",
"related": "http://api.localhost.local:3000/api/v1/categories/1/subcategories"
}
}
}
},
{
"id": "3",
"type": "categories",
"links": {
"self": "http://api.localhost.local:3000/api/v1/categories/3"
},
"attributes": {
"name": "Enabling environment"
},
"relationships": {
"subcategories": {
"links": {
"self": "http://api.localhost.local:3000/api/v1/categories/3/relationships/subcategories",
"related": "http://api.localhost.local:3000/api/v1/categories/3/subcategories"
}
}
}
}
]
}
All these links aren't going to be used. Is there a way I can remove them?
Thank you :)
The solution I found so far was to monkey patch the Resource Serializer (even though this solution is far from perfect).
module JSONAPI
class ResourceSerializer
def link_object_to_many(source, relationship, include_linkage)
include_linkage = include_linkage | relationship.always_include_linkage_data
link_object_hash = {}
link_object_hash[:links] = {} if relationship.always_include_linkage_data
link_object_hash[:links][:self] = self_link(source, relationship) if relationship.always_include_linkage_data
link_object_hash[:links][:related] = related_link(source, relationship) if relationship.always_include_linkage_data
link_object_hash[:data] = to_many_linkage(source, relationship) if include_linkage
link_object_hash
end
def link_object_to_one(source, relationship, include_linkage)
include_linkage = include_linkage | #always_include_to_one_linkage_data | relationship.always_include_linkage_data
link_object_hash = {}
link_object_hash[:links] = {} if relationship.always_include_linkage_data
link_object_hash[:links][:self] = self_link(source, relationship) if relationship.always_include_linkage_data
link_object_hash[:links][:related] = related_link(source, relationship) if relationship.always_include_linkage_data
link_object_hash[:data] = to_one_linkage(source, relationship) if include_linkage
link_object_hash
end
end
end

JSON API Resources relationship attributes

I have two models related :
class Item < ActiveRecord::Base
belongs_to :carousel
end
And
class Carousel < ActiveRecord::Base
has_many :items
end
I trying to open API to carousels using the JSON API Resources gem, i need to show carousel attributes and some items attributes, something like this:
{
"data": [
{
"id": "1",
"type": "carousels",
"links": {
"self": "http://localhost:3000/api/v1/carousels/1"
},
"attributes": {
"name": "primary",
"items": [
{
"title": "first item",
"file-url": "url",
"index": 0
},
{
"title": "second item",
"file-url": "url",
"index": 1
}
]
}
}
]
}
My carousel resource:
module Api
module V1
class CarouselResource < JSONAPI::Resource
immutable
attributes :name, :items
def self.records(options = {})
user = options[:context][:current_user]
user.carousels
end
end
end
end
My result:
{
"data": [
{
"id": "1",
"type": "carousels",
"links": {
"self": "http://localhost:3000/api/v1/carousels/1"
},
"attributes": {
"name": "primary",
"items": [
{
"id": 3,
"carousel_id": 1,
"file": {
"url": "url"
},
"title": "first item",
"kind": 0,
"index": 0,
"created_at": "2017-02-23T10:31:53.592-03:00",
"updated_at": "2017-03-01T10:30:52.533-03:00"
},
{
"id": 5,
"carousel_id": 1,
"file": {
"url": "url"
},
"title": "second item",
"kind": 0,
"index": 1,
"created_at": "2017-03-01T10:30:07.011-03:00",
"updated_at": "2017-03-01T10:30:07.011-03:00"
}
]
}
}
]
}

Resources