Reputation: 4129
If I create a child node in RABL using the node() method, how can I control the attributes that are presented?
The JSON output is this:
[
{
"location": {
"latitude": 33333,
"longitude": 44444,
"address": "xxxxxxx",
"title": "yyyy",
"url": "http://www.google.com",
"rate": {
"created_at": "2012-09-02T11:13:13Z",
"id": 1,
"location_id": 1,
"pair": "zzzzzz",
"updated_at": "2012-09-02T12:55:28Z",
"value": 1.5643
}
}
}
]
I want to get rid of the created_at, updated_at and location_id attributes.
I have this in my view file:
collection @locations
attributes :latitude, :longitude, :address, :title, :url
node (:rate) do
|location| location.rates.where(:pair => @pair).first
end
I tried using a partial and the 'extend' method, but it totally screwed things up. Also, I tried adding attributes to the block but it didn't work (the output was as specified in the attributes but it didn't show the values for each attribute).
Thanks!
Upvotes: 1
Views: 5653
Reputation: 1455
Your code: location.rates.where(:pair => @pair).first
returns the whole Rate object. If you want specific fields (for example: all, except for create_at, updated_at, etc.) then you have two options:
Manually describe the hash in node():
node (:rate) do |location|
loc = location.rates.where(:pair => @pair).first
{ :pair => loc.pair, :value => loc.value, etc... }
end
Or you can do this:
node (:rate) do |location|
location.rates.where(:pair => @pair).select('pair, value, etc...').first
end
...and as a side note, I should say that placing logic (rates.where) in your view is not a best practice. see if your controller can do that for the view using the Rate model.
Upvotes: 2
Reputation: 1613
You wouldn't be able to use attributes
within the node block, since "self" in there is still the root object or collection, so in your case @locations
. See also RABL wiki: Tips and tricks (When to use Child and Node)
In the node block you could simply create your custom response by only listing the attributes that your interested in:
node :rate do |location|
rate = location.rates.where(:pair => @pair).first
{:id => rate.id, :location_id => rate.location_id, :value => rate.value}
end
You can also try the approach using a partial:
In app/views/rates/show.json.rabl
object @rate
attributes :id, :location_id, :value
Then in your @locations rabl view:
node :rate do |location|
rate = location.rates.where(:pair => @pair).first
partial("rates/show", :object => rate)
end
Upvotes: 2