0

I have an app where there I have normal ActiveRecord ids as well as a unique field (e.g. ident) that's unique on an external, canonical database. A model looks like:

class Parent
  has_many :childs, foreign_key: :parent_ident, primary_key: :ident
end

class Child
  belongs_to :parent, foreign_key: :parent_ident, primary_key: :ident
end

For various reasons I'd like the consumer of my Rails API to use the canonical ids (e.g. ident) not the ids defined on the app. So I've defined my serializers (using ActiveModel::Serializer):

class ParentSerializer < ActiveModel::Serializer
  attributes :id, :ident, :other, :stuff
  has_many :children

  def id
    object.ident
  end
end

class ChildSerializer < ActiveModel::Serializer
  attributes :id, ident, :parent_ident, :things

  def id
    object.ident
  end
end

the problem is that the JSON generated correctly is using my overridden IDs for the top-level attributes but the IDs in the child_ids field are the local ids not the canonical idents I want to use.

{
  parents: [
    {
      id: 1234, // overridden correctly in AM::S
      ident: 1234,  
      other: 'other',
      stuff: 'stuff',    
      child_ids: [ 1, 2, 3 ], // unfortunately using local ids
    }
  ],
  childs: [
    {
      id: 2345, // doesn't match child_ids array
      ident: 2345, 
      parent_ident: 1234,
      things: 'things'
    }
  ]
}

Question: is there a way to make the parent serializer use the ident field of it's association rather than the default id field?

I have tried putting a def child_ids in the ParentSerializer without success.

I am using Rails 4.2 and the 9.3 version of active_model_serializers gem.

GSP
  • 3,763
  • 3
  • 32
  • 54

1 Answers1

0

You can specify custom serializers for associations as per the docs

has_many :children, serializer: ChildSerializer
penner
  • 2,707
  • 1
  • 37
  • 48
  • Thank you. I don't believe that's the problem (the correct `ChildSerializer` is being used without having to specify it) since the problem is in the parent's rendering of it's child's ids (not the rendering of the child itself). Basically, it's the `child_ids: [ id1, id2, id3 ]` should be `child_ids: [ ident1, ident2, ident3 ]`. – GSP Sep 11 '15 at 21:17
  • You could always do this in the database as well and then just serialize the output as is. SELECT ident AS id ... just spit balling ideas... You can do logic in the serialization methods, do you have context of the caller at all? – penner Sep 11 '15 at 22:39