Search code examples
ruby-on-rails-4active-model-serializersjson-api

Serialize 2 level nested attributes using active model serializers


I am having a trouble in getting the nested attributes during the serialization. Below is my OptionType model which has many OptionValues associated to it.

#app/models/option_type.rb
class OptionType < ActiveRecord::Base
  # Plugins
  translates :name, :description
  accepts_nested_attributes_for :translations, allow_destroy: true, reject_if: :all_blank
  # Associations
  has_many :option_values, inverse_of: :option_type, dependent: :destroy
  # Nested Attributes
  accepts_nested_attributes_for :translations
end

Below is my OptionValue model which belongs to an OptionType and has one OptionImage associated to it.

#app/models/option_value.rb
class OptionValue < ActiveRecord::Base
  # Plugins
  translates :name, :description
  # Associations
  belongs_to :option_type, inverse_of: :option_values
  has_one :option_image, as: :viewable, inverse_of: :option_value
  # Nested Attributes
  accepts_nested_attributes_for :translations
  accepts_nested_attributes_for :option_image, allow_destroy: true,        
end

Below is the OptionImage model which belongs to an OptionValue.

#app/models/option_image.rb
class OptionImage < Asset
  # Associations
  belongs_to :option_value, inverse_of: :option_image
end

When serializing an OptionType model, I want the information regarding option_values as well as the associated images. Below is my OptionTypeSerializer which is returning the option_values associated to it, but I have no idea how to fetch the associated images as well while serializing this.

#app/serializers/option_type_serializer.rb
class OptionTypeSerializer < ActiveModel::Serializer
  attributes :id, :key, :customizable, :name, :option_values

  def option_values
    object.option_values
  end
end

-How do I fetch the images for the option_value in their respective JSON objects?

-How do I customize this json to get only a few attributes say name and id inside the option_value?

I've tried using the usual has_many and belongs_to inside the OptionTypeSerializer, but it doesn't work.

Below is the JSON returned by this serializer. // http://0.0.0.0:3000/products/786/customize.json

{
  "data": [
    {
      "id": "1",
      "type": "option-types",
      "attributes": {
        "key": "fabric",
        "customizable": true,
        "name": "FABRIC",
        "option-values": [
          {
            "id": 1,
            "key": "Cotton",
            "name": "Cotton",
            "description": ""
          },
          {
            "id": 2,
            "key": "Linen"
            "description": ""
          },
          {
            "id": 3,
            "key": "polyster",
            "name": "Polyster",
            "description": ""
          },
          {
            "id": 4,
            "key": "egyptian cotton",
            "name": "Egyptian Cotton",
            "description": ""
          }
        ]
      }
    },
    {
      "id": "2",
      "type": "option-types",
      "attributes": {
        "key": "cuff-type",
        "name": "CUFF TYPE",
        "option-values": [

        ]
      }
    },
    {
      "id": "3",
      "type": "option-types",
      "attributes": {
        "key": "vents",
        "name": "VENTS",
        "option-values": [

        ]
      }
    }
  ]
}

Solution

  • Do you have an option values serializer?

    In there, you'd just specify a property with a method that maybe goes something like:

    OptionValueSerializer < ActiveModel::Serializer
      attributes :id, :image
    
      def image
       object.option_image.url # or whatever methood
      end
    end