Domanda

Sto cercando di costruire una rappresentazione JSON di alcuni modelli di rotaie utilizzando il serializzatore del modello attivo, dove alcuni modelli incorrono altri. Ad esempio, ho eventi e partecipanti, evento has_and_belongs_to_many partecipanti.

class EventSerializer < ActiveModel::Serializer
  attributes :name

  has_many :attendees, serializer: AttendeeSerializer
end

class AttendeeSerializer < ActiveModel::Serializer
  attributes :name
end
.

Ciò comporterebbe JSON come { name: 'Event One', attendees: [{ name: 'Alice' }, { name: 'Bob' }] }.

Ora, vorrei aggiungere ciò che i partecipanti hanno detto sull'evento. Diciamo, comment fost_apper_to event, fost_to partecipante. Mi piacerebbe includere tali commenti nell'output serializzato dell'evento, quindi diventerebbe { name: 'Event One', attendees: [{ name: 'Alice', comments: [{ text: 'Event One was great!'}] }, { name: 'Bob', comments: [] }] }.

Potrei avere

class AttendeeSerializer < ActiveModel::Serializer
  attributes :name

  has_many :comments
end
.

Ma questo selezionerebbe tutti i commenti di questo partecipante per tutti gli eventi - non quello che voglio. Mi piacerebbe scrivere questo, ma come trovo il particolare evento per il quale sto facendo la serializzazione? Posso in qualche modo accedere all'oggetto "genitore" o forse passare opzioni a un serializzatore ha 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
.

è questo qualcosa che può essere fatto, o dovrei solo costruire il JSON in un altro modo per questo particolare caso d'uso?

È stato utile?

Soluzione

Farei le cose manualmente per ottenere il controllo:

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
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top