Active_model_serializers: Dynamic serializer selection

Created on 7 May 2016  路  6Comments  路  Source: rails-api/active_model_serializers

Currently the serializer param on has_x takes an object.

It would be cool if it could accept a method name as well.

Use case:

Dynamically setting the serializer for polymorphic relationships:

has_one :user, polymorphic: true, serializer: :serializer_picker

def serializer_picker
   if user.class == 'Admin'
     SparseAdminSerializer
   end
 end

Most helpful comment

@KevinColemanInc you can use this:

class MySerializer < ActiveModel::Serializer
  def self.serializer_for(model, options)
    return SparseAdminSerializer if model.class == 'Admin'
    super
  end

  # the rest of the serializer
end

At the moment there is no better solution available.

All 6 comments

cant you just do this as an attribute then and make a method for said attribute?

class SomeSerializer < ApplicationSerializer
  attributes :id, :somefakerelationship

  def somefakerelationship
     ## do stuff
    ## profit?
  end

I think if the method generates a model, that models serializer should spawn?

@cgmckeever true, but I want to specify the serializer of the thing that spawned. For my particular use case, I am have a model called "Notification" It has a source_obj polymorphic relationship on it such that many different models can be a source_obj.

The default model's serializer is often too big for what I want. So I want to the source_obj to have use special "sparse" serializers for each object. e.g. sparse_user_serializer, sparse_profile_serializer, etc. etc. instead of the default model serializer of user_serializer or profile_serializer.

does that make sense?

I think my hack to fix this will be to do:

class SomeSerializer < ApplicationSerializer
  attributes :id, :source_obj

  def source_obj
    object.source_obj.as_json
  end
end

so I am at least not accidently getting any N+1s

@KevinColemanInc you can use this:

class MySerializer < ActiveModel::Serializer
  def self.serializer_for(model, options)
    return SparseAdminSerializer if model.class == 'Admin'
    super
  end

  # the rest of the serializer
end

At the moment there is no better solution available.

@groyoh NICE!

Cool! I will use that.

We should document this. PR anyone?

Was this page helpful?
0 / 5 - 0 ratings