I\'m looking to render an index of all articles along with a full article via JSON in my rails app, but I\'m having a little trouble figuring out how to do it.
Here
(Please accept an answer)
I think that the link that nirvdrum gave holds your answer. I only answer because nobody has mentioned encode_json
.
In your case you should only be dealing with as_json
. Either by building a hash (with various calls to as_json
) and sending that to render :json => ...
(without the call to to_json
) or by simply implementing as_json
on your model and letting rails do all the work. (But I suspect you'll need the former.)
If you really need some fancy js in your rendered response then you can implement encode_json
in your classes (again, not to_json
). For example:
class JsEmptyClosure
def encode_json(*args)
"jQuery[\"noop\"] || function(){}"
end
def as_json(*args) self end
end
This will now respond to to_json
with valid js (but note it's not actually json).
to_json has a :method option that includes the result of any method you name, you could define a method on that model that returns the additional data you want in your JSON.
Just to be clear the code above works with the :include and :except. And by works I mean it doesn't throw an error. The problem is it includes comments for every article in the index. I'm only looking to include comments for the :item and not any of the articles listed in the index.
I couldn't get nesting to work as a hash or an OpenStruct object.
Nesting on :include throws an error, nesting on :except doesn't throw an error, but nothing is filtered out, :created_at, etc. still show up.
...
@response = { :item => @article, :index => @index }
format.js { render :json => @response.to_json(
:except => {:item => [ :created_at, :updated_at, :draft, :id, :publish ]},
:include => { :item => {
:comments => {
:only => [:body]
}
}}),
:callback => params[:callback]}
end
Thanks for the question, I am able to customize my json format for a model with several associations.
render json: @posts.to_json(
:except => [ :created_at, :updated_at, :user_id ],
:include => {
:user => {:only => [:email, :phone]},
:location => {:only => [:title, :lat, :lon, :street, :city, :state, :zipcode]},
:uploads => {:only => [:image]}
}
)
You should be able to nest the :include
, :except
, etc. like so:
:except => {:item => [ :created_at, :updated_at, :draft, :id, :publish ]}...
If that doesn't work, make it an object (e.g. an OpenStruct) instead of a hash.
-- Markus
I would recommend overloading the attributes method to return an alternat hash that will be automatically used in to_json output.
class Article
def attributes
{ ... } # define your hash that you want to return at the '...'
end
end
To me this seems much simpler than mucking around with to_json directly.