Frage

Ich versuche, mithilfe des Active Model Serializer eine JSON-Darstellung einiger Rails-Modelle zu erstellen, wobei einige Modelle andere einbetten.Zum Beispiel habe ich Event und Teilnehmer, Event 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

Dies würde zu einem JSON-ähnlichen Ergebnis führen { name: 'Event One', attendees: [{ name: 'Alice' }, { name: 'Bob' }] }.

Nun möchte ich hinzufügen, was die Teilnehmer über die Veranstaltung gesagt haben.Nehmen wir an, Kommentar gehört_zum Ereignis, gehört_zum Teilnehmer.Ich würde diese Kommentare gerne in die serialisierte Ausgabe von event aufnehmen, damit es so wird { name: 'Event One', attendees: [{ name: 'Alice', comments: [{ text: 'Event One was great!'}] }, { name: 'Bob', comments: [] }] }.

ich könnte haben

class AttendeeSerializer < ActiveModel::Serializer
  attributes :name

  has_many :comments
end

aber das würde alle Kommentare dieses Teilnehmers für alle Veranstaltungen auswählen – nicht das, was ich möchte.Ich würde das gerne schreiben, aber wie finde ich das bestimmte Ereignis, für das ich die Serialisierung durchführe?Kann ich irgendwie auf das „übergeordnete“ Objekt zugreifen oder Optionen an einen has_many-Serializer übergeben?

class AttendeeSerializer < ActiveModel::Serializer
  attributes :name

  has_many :comments

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

Ist das möglich, oder sollte ich JSON für diesen speziellen Anwendungsfall einfach auf andere Weise erstellen?

War es hilfreich?

Lösung

Ich würde die Dinge manuell erledigen, um die Kontrolle zu erlangen:

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top