Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use ActiveModel::Serializers to include two parent json arrays

I'm trying to send my front-end application json that looks like this:

{
  facilities: [
     {id: 5, name: 'happy days ranch', location: { address: '1424 Pastoral Lane', zipcode: '25245'}, instructor_ids: [2, 4, 9]}
  ],
  instructors: [
     {id: 4, name: 'Johnny Pheonix', skill: '8', picture: 'aws_url', facility_ids: [5, 8, 12}
  ]
}

Things I have tried

render :json => @facilities 

The serializer discovers this. Yay! But this does not include any instructors

render :json => {facilities: @facilities, instructors: @instructors}

This gives me an instructors array and a facilities array, but activeModel::Serializers is not used.

render :json => [@facilities, @instructors]

At first I was excited about this one, because it gave me two arrays, and it used ActiveModel::Serializers. However, this is what the JSON looked like:

{facilities: [
  {facilities: [
    #my facilities data
  ]},
  {facilities: [
    #my instructor data
  ]}
]}

Is what I'm trying to do even allowed by ActiveModel::Serializers? If so, how?

Thanks much in advance!

like image 902
Jeffrey Biles Avatar asked May 11 '13 21:05

Jeffrey Biles


2 Answers

I solved it by creating a class called Search that incorporates aspects of ActiveModel

class Search
  include ActiveModel::Serialization
  include ActiveModel::SerializerSupport

  attr_accessor :facilities, :instructors

  def initialize(facilities, instructors)
    @facilities, @instructors = facilities, instructors
  end
end

Then I created a Searches controller (nothing interesting there) and a Search serializer.

class SearchSerializer < ActiveModel::Serializer
  has_many :instructors, embed: :objects
  has_many :facilities, embed: :objects
end

This creates my desired json, although now it is wrapped in a search hash:

{search: {
  #the stuff I wanted 
}}
like image 118
Jeffrey Biles Avatar answered Sep 30 '22 12:09

Jeffrey Biles


This is my solution:

render json: {
  facilities: ActiveModel::ArraySerializer.new(@facilities, each_serializer: FacilitySerializer, root: false),
  instructors: ActiveModel::ArraySerializer.new(@instructors, each_serializer: InstructorSerializer, root: false)
}

It's a little bit dirty. It basically instantiates what would be instantiated except done manually and twice. Both result sets are rendered using ActiveModel::Serializers in the correct format.

like image 31
kequc Avatar answered Sep 30 '22 14:09

kequc