Question

J'essaie de créer une représentation JSON de certains modèles Rails à l'aide d'Active Model Serializer, où certains modèles en intègrent d'autres.Par exemple, j'ai un événement et des participants, un événement has_and_belongs_to_many Attendees.

class EventSerializer < ActiveModel::Serializer
  attributes :name

  has_many :attendees, serializer: AttendeeSerializer
end

class AttendeeSerializer < ActiveModel::Serializer
  attributes :name
end

Cela donnerait un JSON comme { name: 'Event One', attendees: [{ name: 'Alice' }, { name: 'Bob' }] }.

Maintenant, j'aimerais ajouter ce que les participants ont dit à propos de l'événement.Disons que le commentaire appartient_à l'événement, appartient_au participant.J'aimerais inclure lesdits commentaires dans la sortie sérialisée de l'événement, afin que cela devienne { name: 'Event One', attendees: [{ name: 'Alice', comments: [{ text: 'Event One was great!'}] }, { name: 'Bob', comments: [] }] }.

J'aurais pu

class AttendeeSerializer < ActiveModel::Serializer
  attributes :name

  has_many :comments
end

mais cela sélectionnerait tous les commentaires de ce participant pour tous les événements - pas ce que je veux.J'aimerais écrire ceci, mais comment trouver l'événement particulier pour lequel je fais la sérialisation ?Puis-je accéder d'une manière ou d'une autre à l'objet « parent », ou peut-être transmettre des options à un sérialiseur has_many ?

class AttendeeSerializer < ActiveModel::Serializer
  attributes :name

  has_many :comments

  def comments
    object.comments.where(event_id: the_event_in_this_context.id)
  end
end

Est-ce quelque chose qui peut être fait, ou dois-je simplement créer le JSON d'une autre manière pour ce cas d'utilisation particulier ?

Était-ce utile?

La solution

Je ferais les choses manuellement pour prendre le contrôle :

class EventSerializer < ActiveModel::Serializer
  attributes :name, :attendees

  def attendees
    object.attendees.map do |attendee|
      AttendeeSerializer.new(attendee, scope: scope, root: false, event: object)
    end
  end
end

class AttendeeSerializer < ActiveModel::Serializer
  attributes :name, :comments

  def comments
    object.comments.where(event_id: @options[:event].id).map do |comment|
      CommentSerializer.new(comment, scope: scope, root: false)
    end
  end
end
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top