Rails 4 render json nested objects

11,322

Solution 1

I got it.

render :json => @booking, :include => [:paypal, 
                                       :boat_people,
                                       :boat => {:only => :name, :include => {:port => {:only => :name, :include => {:city => {:only => :name, :include => {:country => {:only => :name}}}}}, 
                                                :boat_model => {:only => :name, :include => {:boat_type => {:only => :name}}}}}]

Solution 2

You are probably going to want a much more robust system for displaying JSON. The built-in Rails helpers are really designed primarily for simple additions that enable users to do most of what they would want to accomplish. However, in your case, you are trying to make it do more than it was designed for.

I would highly recommend either creating a view object or using a gem like RABL.

My preference is to use Rabl for complex JSON. It basically creates the 'view object' for you by building a domain specific language that makes it relatively easy to build complex JSON objects in rails.

RABL basically allows you to build views that format JSON instead of HTML. The DSL is extremely rich and enables you to do just about anything you would want. In your case, I think the code would look something like this:

app/views/bookings/show.rabl

object @booking
#these are attributes that exist on your booking model: 
attributes :booking_attribute, :other_booking_attribute

child :paypal do
  #these are attributes that exist on your paypal model:
  attributes :paypay_attribute1, :other_paypal_attribute
end

child :boat_people do
  #boat_people attributes that you want to include
  attributes :blah_blah
end

child :boat do
  #boat attributes that you want to include
  attributes :boat_attribute1, :boat_attribute2

  child :boat_model do
    attributes :name

    child :boat_type do
      attributes :name
    end
  end

end
Share:
11,322
Rober
Author by

Rober

Updated on July 03, 2022

Comments

  • Rober
    Rober almost 2 years

    I need to render as Json a complex structure. I have next structure working:

    render :json => @booking, :include => [:paypal, 
                                           :boat_people,
                                           :boat => {:only => :boat_model, :include => {:boat_model => {:only => :name, :include => { :boat_type => {:only => :name}}}}}] 
    

    but I´m not able to add a port attribute with some other nested attributes to :boat, such as :boat_model (at same level).

    UPDATE:

    Although it´s not working, I include my port attribute.

    render :json => @booking, :include => [:paypal, 
                                           :boat_people,
                                           :boat => {:only => [:boat_model => {:include => {:boat_model => {:only => :name, :include => { :boat_type => {:only => :name}}}}},
                                                               :port => {:include => :city => {:only => name}}]}]
    

    I mean, boat_model and port are both boat attributes.

    This is the model object:

    class Boat < ActiveRecord::Base
    
      attr_accessor :price
      @price
    
      attr_accessor :extrasPrice
      @extrasPrice
    
      def as_json(options = { })
        h = super(options)
        h[:price] = @price    
        h[:extrasPrice] = @extrasPrice
        h
      end
    
    
      belongs_to :boat_model
      belongs_to :port
      belongs_to :state
      has_many :photos
    end