Search code examples
ruby-on-railsjsonactive-model-serializersrails-api

How do I select which attributes I want for active model serializers relationships


I am using the JSONAPI format along with Active Model Serializers to create an api with rails-api.

I have a serializer which shows a specific post that has many topics and currently, under relationships, lists those topics. It currently only lists the id and type. I want to show the title of the topic as well.

Some would say to use include: 'topics' in my controller, but I don't need the full topic record, just its title.

Question: How do I specify which attributes I want to show from topics?

What I have

"data": {
  "id": "26",
  "type": "posts",
  "attributes": {
    "title": "Test Title 11"
  },
  "relationships": {
    "topics": {
      "data": [
        {
          "id": "1",
          "type": "topics"
        }
      ]
    }
  }
}

What I want

"data": {
  "id": "26",
  "type": "posts",
  "attributes": {
    "title": "Test Title 11"
  },
  "relationships": {
    "topics": {
      "data": [
        {
          "id": "1",
          "type": "topics",
          "title": "Topic Title"
        }
      ]
    }
  }
}

My current serializer classes EDIT: this is what I'm after please.

class PostSerializer < ActiveModel::Serializer
  attributes :title

  belongs_to :domain
  belongs_to :user

  has_many :topics, serializer: TopicSerializer

  def topics
    # THIS IS WHAT I AM REALLY ASKING FOR
  end
end

class TopicSerializer < ActiveModel::Serializer
  attributes :title, :description

  belongs_to :parent
  has_many :children
end

One thing I tried - there is an answer below that makes this work, but its not really what I'm after.

class PostSerializer < ActiveModel::Serializer
  attributes :title, :topics

  belongs_to :domain
  belongs_to :user

  def topics
    # THIS WAS ANSWERED BELOW! THANK YOU
  end
end

Solution

  • Just make sure to return a hash or array of hashes like so:

    def videos
        object.listing_videos.collect do |lv|
          {
            id: lv.video.id,
            name: lv.video.name,
            wistia_id: lv.video.wistia_id,
            duration: lv.video.duration,
            wistia_hashed_id: lv.video.wistia_hashed_id,
            description: lv.video.description,
            thumbnail: lv.video.thumbnail
          }
        end
      end