web-dev-qa-db-fra.com

Comment implémenter plusieurs sérialiseurs différents pour le même modèle en utilisant ActiveModel :: Serializers?

Supposons que vous implémentez une API REST dans Rails. Lorsque vous servez une collection, vous souhaiterez peut-être n'inclure que quelques attributs:

/people

Mais lorsque vous servez une seule ressource, vous souhaitez inclure tous les attributs:

/people/1

Je ne vois pas comment faire cela en utilisant ActiveModel :: Serializers, puisque les exemples utilisent tous le modèle de définition d'un sérialiseur par modèle (avec une convention de dénomination standard) et que AMS utilise automatiquement le bon dans le contrôleur lorsque vous le faites:

render json: @people

ou:

render json: @person
36
odigity

Pour éviter de mélanger les problèmes de vue dans vos modèles (via des variantes sérialisées), utilisez la vue pour rendre votre JSON pour chaque action, tout comme nous le faisons pour le HTML.

jbuilder & rabl remplissent très bien ce besoin de création de modèles de données.

Mise à jour 2013-12-16 : la bibliothèque ActiveModelSerializers prend en charge la définition de plusieurs sérialiseurs pour un modèle, comme @phaedryx a répondu plus tard, en utilisant sérialiseurs personnalisés .

4
Mars

Vous pouvez avoir plusieurs sérialiseurs pour le même modèle, par ex.

class SimplePersonSerializer < ActiveModel::Serializer
  attributes :id, :name
end

et

class CompletePersonSerializer < ActiveModel::Serializer
  attributes :id, :name, :phone, :email
end

informations simples pour les personnes dans un seul contrôleur:

render json: @people, each_serializer: SimplePersonSerializer

informations complètes pour les personnes dans un autre:

render json: @people, each_serializer: CompletePersonSerializer

info simple pour une personne seule:

render json: @person, serializer: SimplePersonSerializer

infos complètes pour une personne seule:

render json: @person, serializer: CompletePersonSerializer
113
phaedryx
class CompletePersonSerializer < ActiveModel::Serializer
  root :person
  attributes :id, :name, :phone, :email
end

ou

render json: @people, each_serializer: CompletePersonSerializer, root: :person
10
Alexey Pismenskiy

Pour ajouter à ce que @phaedryx a dit, ce que je fais pour cela, c'est appeler une méthode qui renvoie le bon sérialiseur ... pour votre question, j'utiliserais:

class MyController < ApplicationController

  def index
    render json: @people, each_serializer: serializer_method
  end

  private

  def serializer_method
    defined?(@people) ? PeopleSerializer : PersonSerializer
  end

end
2
tehprofessor