Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActiveModelSerializers Polymorphic Json

Been wrestling with trying to get polymorphic serializers working and testing data via rspec. Just upgraded to 0.10+

I found this post, which makes a lot of sense, and does give me a entry into generating the serializations, however, when doing it for polymorphs, I never get the type and id properly named (expecting to see asset_id and asset_type nested)

{:id=>1,
  :label=>"Today I feel amazing!",
  :position=>0,
  :status=>"active",
  :media_container_id=>1,
  :asset=>
    {:id=>4

Test ActiveModel::Serializer classes with Rspec

class MediaSerializer < ApplicationSerializer
  attributes :id,
             :label,

  has_one :asset, polymorphic: true
end

I noticed that the tests dont even seem to properly add the polymorphic identifiers either (ie asset_id, asset_type -- or in the test case imageable_id, imageable_type)

https://github.com/rails-api/active_model_serializers/commit/045fa9bc072a04f5a94d23f3d955e49bdaba74a1#diff-c3565d7d6d40da1b2bf75e13eb8e6afbR36

If I go straight up MediaSerialzer.new(media) I can poke at the .associations, but I cant seem to get them to render as if I was generating a full payload

From the docs https://github.com/rails-api/active_model_serializers

serializer_options = {}
serializer = SomeSerializer.new(resource, serializer_options)
serializer.attributes
serializer.associations

Im pretty sure Im missing something/doing something wrong - any guidance would be great.

Thanks

like image 274
cgmckeever Avatar asked May 02 '16 03:05

cgmckeever


1 Answers

It isn't easy to get the effect you are looking for, but it is possible.

You can access the hash generated by the serializer by overriding the associations method.

class MediaSerializer < ApplicationSerializer
  attributes :id,
             :label,

  has_one :asset, polymorphic: true

  def associations details
    data = super
    data[:asset] = relabel_asset(data[:asset])
    data
  end

  def relabel_asset asset
    labelled_asset = {}
    asset.keys.each do |k|
      labelled_asset["asset_#{k}"] = asset[k];
    end
    labelled_asset
  end
end

I learnt alot about ActiveModelSerializer to get the hang of this! I referred to Ryan Bates' podcast on the topic:

http://railscasts.com/episodes/409-active-model-serializers

In there he describes how you can override the attributes method and call super to get access to the hash generated by the serializer. I guessed I could do the same trick for the associations method mentioned in your post. From there it takes a little bit of Ruby to replace all the keys, but, if I have understood correctly what you require, it is technically possible.

Hope that helps!

like image 177
peregrine42 Avatar answered Sep 18 '22 14:09

peregrine42