2017-02-06 2 views
0

В некоторых случаях в JSON встроены вложенные ассоциации, в других - нет. Пока все хорошо, что ведет себя так, как я хочу. Но я хочу, чтобы в тех случаях, когда они не были внедрены, идентификаторы вложенных ассоциаций все еще испускаются.Включить идентификаторы вложенных ассоциаций в сериализаторах ActiveModel

Например:

class FooSerializer < ActiveModel::Serializer 
    attributes :id, :x, :y 
    belongs_to :bar 
end 

class BarSerializer < ActiveModel::Serializer 
    attributes :id, :z 
end 

Когда я сериализация Foo объекта без include: [:bar] Я хочу, чтобы результат выглядеть следующим образом:

{ 
    "id": 123 
    "x": 1, 
    "y": 2, 
    "bar": 456 
} 

И если bar бы полиморфное объединение Я хотел бы что-то вроде что:

{ 
    "id": 123 
    "x": 1, 
    "y": 2, 
    "bar": {"id": 456, "schema": "Bar"} 
} 

A В конце концов, я хотел бы, чтобы идентификаторы были строками ("id": "123"), потому что они должны быть черными ящиками для потребителя API и определенно не использовать тип JavaScript Number (что равно double точности с плавающей запятой!).

Как это сделать? Я не нашел никакой информации об этом.

ответ

0

Определить атрибуту id этот путь в FooSerializer, чтобы получить его в виде строки:

attribute :id do 
    object.to_s 
end 

«Когда я сериализовать объект Foo без включения: [: бар] Я хочу, чтобы результат выглядит следующим образом:»

attribute :bar do 
    object.bar.id.to_s 
end 

«И если бар будет полиморфные ассоциациями Я хотел бы что-то подобное:»

attribute :bar do 
    {id: object.barable_id.to_s, schema: object.barable_type} 
end 

ПРИМЕЧАНИЕ: Я не тестировал это.

+0

Да, это та часть, и я поставил что-то подобное, что в 'BaseSerializer'. Но как насчет остальных? – panzi

+0

Я отредактировал ответ. Однако я его не тестировал. – archana

+0

Но я не могу это сделать в центральном месте, не повторяя это снова и снова в наших десятках сериализаторов с несколькими отношениями каждый? – panzi

0

Я нашел способ сделать это с помощью BaseSerializer вроде этого:

class BaseSerializer < ActiveModel::Serializer 
    attributes :id, :type 

    def id 
     if object.id.nil? 
      nil 
     else 
      object.id.to_s 
     end 
    end 

    def type 
     # I also want all the emitted objects to include a "type" field. 
     object.class.name 
    end 

    def self.belongs_to(key, *args, &block) 
     attribute key do 
      assoc = object.class.reflect_on_association(key) 
      foreign_id = object.send(assoc.foreign_key) 
      if foreign_id.nil? 
       nil 
      elsif assoc.polymorphic? 
       { 
        type: object.send(assoc.foreign_type), 
        id: foreign_id.to_s 
       } 
      else 
       foreign_id.to_s 
      end 
     end 

     super 
    end 
end 
Смежные вопросы