Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 4 render json nested objects

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
like image 804
Rober Avatar asked Dec 16 '13 19:12

Rober


2 Answers

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}}}}}]
like image 193
Rober Avatar answered Nov 02 '22 12:11

Rober


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
like image 3
Joe Edgar Avatar answered Nov 02 '22 13:11

Joe Edgar