Reputation: 638
I am working on a rails 5 api only. I can get all the data that i want, but i would like to customize the output.I tried some solutions, but couldn't find it yet.
This is my portfolio controller:
def show
render json: @portfolio.to_json(
:only => [:title],
:include => {
:cryptos => {
:only => [],
:include => [
{:radarcrypto => { :only => [:ticker, :price] }},
]},
}
)
end
this is the output
{
title: "Portfolio 1",
cryptos: [
{
radarcrypto: {
ticker: "BTC",
price: "190919.85",
}
},
{
radarcrypto: {
ticker: "ETH",
price: "12220.18",
}
},
],
}
But i would like something like that:
{
title: "Portfolio 1",
cryptos:
{
ticker: "BTC",
price: "190919.85",
},
{
ticker: "ETH",
price: "12220.18",
},
}
this are my models
class Portfolio < ApplicationRecord
has_many :cryptos
end
class Radarcrypto < ApplicationRecord
has_many :cryptos
end
class Crypto < ApplicationRecord
belongs_to :portfolio
belongs_to :radarcrypto
end
I already tried to use without success:
class Radarcrypto < ApplicationRecord
ApplicationRecord.include_root_in_json = false
end
I don't know if there is a better solution to this customization, if would be better to use the views, json.jbuilder for example. thanks.
Upvotes: 1
Views: 74
Reputation: 518
It's not possible to include a collection of objects as a value to a key without wrapping them in an array in JSON. (source (W3Schools))
It is possible, on the other hand, to have a collection of objects, but each one would have to have its own unique key. So the response could be shaped as such:
{
title: "Portfolio 1",
cryptos: {
BTC: {
ticker: "BTC",
price: "190919.85",
},
ETH: {
ticker: "ETH",
price: "12220.18",
},
}
(A different key is going to have to be used if more than one radarcrypto
can have the same ticker)
I'm not sure how that would be achieved using the to_json
options (e.g. include
and only
). You could probably do it manually by doing:
def show
portfolio = {};
portfolio['title'] = @portfolio.title
portfolio['cryptos'] = {}
@portfolio.cryptos.each do |crypto|
radarcrypto = crypto.radarcrypto
portfolio['cryptos']["#{radarcrypto.ticker}"] = {
'ticker': radarcrypto.ticker,
'price': radarcrypto.price
}
end
render json: portfolio.to_json
end
A gem such as Jbuilder may be a good candidate if nested shaping of JSON responses is done in multiple controllers.
Upvotes: 1