Search code examples
ruby-on-railsactive-model-serializers

How to return parent data from Rails ActiveModelSerializers?


How can i return parent data from Rails ActiveModelSerializers?

This is my Model

class User < ActiveRecord::Base

  has_many :user_groups ,dependent: :destroy
  has_many :groups , through: :user_groups

end

class Group < ActiveRecord::Base

  has_many :user_groups ,dependent: :destroy
  has_many :users , through: :user_groups

end

class UserGroup < ActiveRecord::Base

  belongs_to :user
  belongs_to :group

end

This is my Serializer

class UserSerializer < ActiveModel::Serializer
  attributes :id ,:email, :username, :fullname, :grade,:auth_token

  has_many :user_groups

end

class GroupSerializer < ActiveModel::Serializer
  attributes :id ,:name ,:court_price ,:shuttle_price
  has_many :user_groups
end

class UserGroupSerializer < ActiveModel::Serializer
  attributes :id , :level

  belongs_to :user_id

end

This is my controller

def member_list
  group = current_user.groups.find_by(id: params[:id])

  respond_with group
end

So i want to return UserGroup data with User data inside but this is what i got.

enter image description here

{
  "id": 35,
  "name": "test 01",
  "court_price": 150,
  "shuttle_price": 12,
  "user_groups": [
    {
      "id": 30,
      "level": "player"
    },
    {
      "id": 29,
      "level": "owner"
    }
  ]
}

How can i return User data inside user_groups array? Thanks!


Solution

  • You've got to be careful with circular references there. Group embeds UserGroup, that embed User, that also embeds UserGroup.

    For that situation, I'd recommend creating a custom serializer for User without the relations. ShallowUserSerializer, for instance.

    class ShallowUserSerializer < ActiveModel::Serializer
      attributes :id ,:email, :username, :fullname, :grade,:auth_token
    end
    

    Aside from that, there's a little problem with UserGroupSerializer. active_model_serializer's docs state:

    Serializers are only concerned with multiplicity, and not ownership. belongs_to ActiveRecord associations can be included using has_one in your serializer.

    So you could rewrite it like this:

    class UserGroupSerializer < ActiveModel::Serializer
      attributes :id , :level
      has_one :user, serializer: ShallowUserSerializer
    end