active_model_serializers icon indicating copy to clipboard operation
active_model_serializers copied to clipboard

How to nest serializers?

Open exocode opened this issue 4 years ago • 2 comments
trafficstars

Expected behavior vs actual behavior

Serialize nested attributes (and exclude some attributes from rendering) I can see the children in json output but the nested Serializer is not

Steps to reproduce

install gem ancestry for polymorphic / self referencing models

model:

class Category
  has_ancestry cache_depth: true, touch: true, counter_cache: true
  attribute :name
  attribute :attribute_to_exclude_from_children_only
end

create some Categories

root = Category.create!(name: "Root")
child = root.children.create!(name: "child1")
baby = child.children.create!(name: "baby")

controller:

class CategoryController < ApplicationController
  def main_menu
      # take one of the following two lines
      roots = Category.roots 
      roots = Category.roots.first.subtree

      render json: roots , each_serializer: MenuSerializer # , include: children <- won't work too
  end
end

Serializers:

class MenuSerializer
     attribute(:name)
     attribute :attribute_to_exclude_from_children_only
     attribute(:children), each_serializer: ChildSerializer
end
class ChildSerializer
   # here only "name" should be rendered, but ALL attributes (created_at, attribute_to_exclude_from_children_only,..) are rendered too... 
     attribute(:name) # I set here a breakpoint, which was called once, but seems not kick in to render properly
     attribute(:children), each_serializer: ChildSerializer
end

what I also tried (maybe some weired things too, but I am quite desperate

  has_many :children, key: :aaa do |child|
    ChildSerializer.new(child)
  end
  has_many :children, key: :bbb, each_serializer: ChildSerializer

  attribute :children, key: :ccc, each_serializer: ChildSerializer
  attribute(:children, key: :ddd, each_serializer: ChildSerializer, include: :children, polymorphic: true)
  class ChildSerializerTest < ActiveModel::Serializer
    attribute :name
  end

Only :ccc and :ddd gets rendered, but with ALL attributes (created_at,...)

Can someone help me to get this going? Thank you VERY MUCH in advance

Environment

ActiveModelSerializers Version (commit ref if not on tag):

Output of ruby -e "puts RUBY_DESCRIPTION": ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin20] OS Type & Version: Darwin 20.3.0 Darwin Kernel Version 20.3.0: Thu Jan 21 00:07:06 PST 2021; root:xnu-7195.81.3~1/RELEASE_X86_64 x86_64 Integrated application and version (e.g., Rails, Grape, etc): Rails "6.1.3.1"

Backtrace

(e.g., provide any applicable backtraces from your application)

Additonal helpful information

(e.g., Gemfile.lock, configurations, PR containing a failing test, git bisect results)

gem 'active_model_serializers', '~> 0.10.0'
  active_model_serializers (~> 0.10.0)
      active_model_serializers (0.10.12)

exocode avatar Apr 12 '21 18:04 exocode

Which adapter are your using?

So a category should be serialized by a menu serializer? And the category's children are not relations? How many levels deep are you trying to serialize?

bf4 avatar Apr 13 '21 04:04 bf4

Which adapter are your using?

Default one (not JsonAPI, or something else)

ActiveRecord PostgreSQL

So a category should be serialized by a menu serializer?

Yes, but only the first category in the chain,... all subcategories should take an other serializer

And the category's children are not relations?

Not real ones, they are methods created by 'ancestry' gem

How many levels deep are you trying to serialize?

Maximum 8

exocode avatar Apr 13 '21 08:04 exocode