简体   繁体   中英

Use alternate association id for ActiveModel::Serializer association

I have an app where there I have normal ActiveRecord ids as well as a unique field (eg 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 (eg 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.

您可以根据文档指定关联的自定义序列化程序

has_many :children, serializer: ChildSerializer

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM