Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to build a JSON response made up of multiple models in Rails
    primarykey
    data
    text
    <h2>First, the desired result</h2> <p>I have <code>User</code> and <code>Item</code> models. I'd like to build a JSON response that looks like this:</p> <pre><code>{ "user": {"username":"Bob!","foo":"whatever","bar":"hello!"}, "items": [ {"id":1, "name":"one", "zim":"planet", "gir":"earth"}, {"id":2, "name":"two", "zim":"planet", "gir":"mars"} ] } </code></pre> <p>However, my <code>User</code> and <code>Item</code> model have more attributes than just those. I found a way to get this to work, but <strong>beware</strong>, it's not pretty... Please help...</p> <h3>Update</h3> <p>The next section contains the original question. The last section shows the new solution.</p> <hr> <h2>My hacks</h2> <h3>home_controller.rb</h3> <pre><code>class HomeController &lt; ApplicationController def observe respond_to do |format| format.js { render :json =&gt; Observation.new(current_user, @items).to_json } end end end </code></pre> <h3>observation.rb</h3> <pre><code># NOTE: this is not a subclass of ActiveRecord::Base # this class just serves as a container to aggregate all "observable" objects class Observation attr_accessor :user, :items def initialize(user, items) self.user = user self.items = items end # The JSON needs to be decoded before it's sent to the `to_json` method in the home_controller otherwise the JSON will be escaped... # What a mess! def to_json { :user =&gt; ActiveSupport::JSON.decode(user.to_json(:only =&gt; :username, :methods =&gt; [:foo, :bar])), :items =&gt; ActiveSupport::JSON.decode(auctions.to_json(:only =&gt; [:id, :name], :methods =&gt; [:zim, :gir])) } end end </code></pre> <hr> <h1>Look Ma! No more hacks!</h1> <h2>Override <code>as_json</code> instead</h2> <p>The <a href="http://api.rubyonrails.org/classes/ActiveRecord/Serialization.html#M001874" rel="nofollow noreferrer">ActiveRecord::Serialization#as_json</a> docs are pretty sparse. Here's the brief: </p> <pre><code>as_json(options = nil) [show source] </code></pre> <p>For more information on <code>to_json</code> vs <code>as_json</code>, see the accepted answer for <a href="https://stackoverflow.com/questions/2572284/override-to-json-in-rails-2-3-5">Overriding to_json in Rails 2.3.5</a></p> <h2>The code sans hacks</h2> <h3>user.rb</h3> <pre><code>class User &lt; ActiveRecord::Base def as_json(options) options = { :only =&gt; [:username], :methods =&gt; [:foo, :bar] }.merge(options) super(options) end end </code></pre> <h3>item.rb</h3> <pre><code>class Item &lt; ActiveRecord::Base def as_json(options) options = { :only =&gt; [:id, name], :methods =&gt; [:zim, :gir] }.merge(options) super(options) end end </code></pre> <h3>home_controller.rb</h3> <pre><code>class HomeController &lt; ApplicationController def observe @items = Items.find(...) respond_to do |format| format.js do render :json =&gt; { :user =&gt; current_user || {}, :items =&gt; @items } end end end end </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload