active_model_serializers icon indicating copy to clipboard operation
active_model_serializers copied to clipboard

be able to override type in serializer

Open InteNs opened this issue 8 years ago • 5 comments

Expected behavior vs actual behavior

expected the following to work:

class SnapshotSerializer < BaseSerializer
  type do
    # semi-code
    if object.poly?
      object.poly_relation_type
    else
       object.type
    end
  end

  attributes :name, :description
end

I can only place a string/symbol right now, and when I try to place lambda the object isn't available in that scope

What I'm really searching for is to be able to dynamically assign type, based on a condition on the object that is being serialized.

Environment

ActiveModelSerializers Version (commit ref if not on tag): 0.10.5

Output of ruby -e "puts RUBY_DESCRIPTION": ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin16]

OS Type & Version: Mac OS 10.12.4

Integrated application and version (e.g., Rails, Grape, etc): Rails

InteNs avatar May 12 '17 16:05 InteNs

@InteNs You can use the instance method json_key and/or a root option as described in https://github.com/rails-api/active_model_serializers/blob/0-10-stable/lib/active_model/serializer.rb#L371-L374

bf4 avatar May 12 '17 18:05 bf4

@bf4 Thanks for the quick response, unfortunately I tried that already, the method never got called.

is it correct that the adapter only calls this method if no explicit serializer was given as described here?

allow me to explain my problem further:

this is my controller code:

  def show
    render json: individual,
      **serializer_options,
      include: params[:include],
      fields: params[:fields]
  end

 # individual.pbt_type = DelayRegistration
  def serializer_options
    {
      serializer: "#{individual.pbt_type}Serializer".constantize
    }
  end

snappable type serializer:

class DelayRegistrationSerializer < SnapshotSerializer

  type 'delay-registrations'

  attributes :reason

  has_one :causing_party
  has_one :causing_party_role
  has_one :delay_code_main
  has_one :delay_code_sub

end

snapshot serializer:

# BaseSerializer directly extends ActiveModel::Serializer
class SnapshotSerializer < BaseSerializer

  attributes :name,
             :description,
             :created_at,
             :updated_at

  has_one :user

  has_many :activities
end

now what I would want is to define type in the snapshot serializer dynamically instead of in each implementation of the polymorphic relationship I tried this in the snapshotserializer but this code wasn't called:

class SnapshotSerializer < BaseSerializer

  def json_key
    'test'
  end

  attributes :name,
             :description,
             :created_at,
             :updated_at

  has_one :user

  has_many :activities
end

InteNs avatar May 12 '17 19:05 InteNs

You linked to the collection serializer. is the snapshot an association?

bf4 avatar May 12 '17 19:05 bf4

my apologies, that link was incorrect

the json_key method in the snapshot serializer doesn't get called and the jsonapi type stays 'snapshots'

the association between snapshot and delay-registration is only on database level, both serializers need to "join together" to create a single endpoint

that's with the type 'delay-registrations' commented out of course.

InteNs avatar May 12 '17 19:05 InteNs

@InteNs the collection serializer is meant to facilitate serialization items in a collection. It doesn't itself have a type. The type comes from the items being serialized.

I'd advise not trying to use the collection serializer directly (unless maybe if you're following how it works in the source code)

bf4 avatar Oct 30 '17 03:10 bf4