Jeremy Thomas
Jeremy Thomas

Reputation: 6694

ActiveModel Serializer for complicated associations

I have 2 associated models:

class User < ActiveRecord::Base
    has_many :notifications, foreign_key: :recipient_id
end

class Notification < ActiveRecord::Base
    belongs_to :recipient, class_name: 'User'
    belongs_to :actor, class_name: 'User'
    belongs_to :notifiable, polymorphic: true
end

I use a serializer for when I load a :user:

class API::UserSerializer < ActiveModel::Serializer
    attributes :id, :email, :auth_token, :location_id, :notifications

    has_many :notifications, foreign_key: :recipient_id, each_serializer: API::NotificationSerializer
end

which in turn uses a serializer for the :notifications:

class API::NotificationSerializer < ActiveModel::Serializer
    attributes :id, :recipient_id, :actor_id, :notifiable_id, :read_at, :action, :recipient, :actor, :notifiable_type

    belongs_to :recipient, serializer: API::RecipientSerializer
    belongs_to :actor
    belongs_to :notifiable, polymorphic: true
end

However, the API::RecipientSerializer is never used, and instead the whole :recipient is returned. What am I doing wrong?


Also, here is the API::RecipientSerializer for good measure:

class API::RecipientSerializer < ActiveModel::Serializer
    attributes :id
end

Upvotes: 0

Views: 1250

Answers (1)

Marcin Kołodziej
Marcin Kołodziej

Reputation: 5313

Two issues:

  1. Check this link. You need to set ActiveModel::Serializer.config.default_includes = '**' if you want your relationships to keep rendering recursively (or set it to whatever you need whenever serializing objects).
  2. Don't add relations to attributes (remove :recipient from attributes in NotificationSerializer). This might work, as your relation will overwrite the attribute, but there's no reason to make them fight.

EDIT: As there seemed to be a problem with setting the default_includes, a specific one was needed while rendering the final result:

render json: user, include: ['notifications', 'notifications.recipient'], status: :ok

Upvotes: 1

Related Questions