Alejandro Araujo
Alejandro Araujo

Reputation: 149

Rails 4 - Simple include multiple JSON inside another JSON

I have the following controller:

  # orders_controller.rb

  def update_quantity
    @product = Product.by_id(params[:product_id])
    @product_details = ProductDetail.availables.by_id(params[:product_id])

    respond_to do |format|
      format.json { render :json => @product.to_json( { :include => [ :current_price, :product_details ] } ) }
    end
  end

I just want to return a JSON with product data, including them current price and products_details, but just the available details (Inventory).

The products and current_price are working good but If I use :product_details, rails includes ALL the details and I want the contained inside @product_details variable.

Thanks

Upvotes: 1

Views: 1239

Answers (2)

Ioannis Tziligkakis
Ioannis Tziligkakis

Reputation: 711

It seems that there is a product_details method in your Product class that returns every ProductDetail record associated with your @product. Most probably it has to do with ActiveRecord association methods when creating associations between models. For example has_many :product_details creates a Product#product_details method so when you serialize a product instance, you serialize product_details as well.

You will have to create a method that returns a subset of the records based on your requirments. For example:

class Product
  has_many :product_details

  def available_product_details
    product_details.available
  end
end

Now you can update your controller to look like this:

OrdersController < ApplicationController
 def update_quantity
    @product = Product.by_id(params[:product_id])    
    respond_to do |format|
      format.json do
        render json: @product.to_json(include: [:current_price, :available_product_details])
      end
    end
  end
end

Upvotes: 1

Mihail Petkov
Mihail Petkov

Reputation: 1545

I am not sure that I understand your question. If product_details doesn't work, try this:

def update_quantity
  @product = Product.by_id(params[:product_id])

  respond_to do |format|
    format.json { 
      render :json => @product.to_json( 
        { 
          :include => [ :current_price ],
          :methods => [ :product_details ] 
        } 
      ) 
    }
  end
end

In your Product model add:

def product_details
  ProductDetail.availables.by_id(self.id)
end

If you want only some fields of product_details:

respond_to do |format|
  format.json { 
    render :json => @product.to_json( 
      { 
        :include => [ 
          :current_price, 
          product_details: {
           only: [
              :field1, 
              :field2
            ]
          }
        ] 
      } 
    ) 
  }
end

Upvotes: 2

Related Questions