Pregunta

Estoy intentando crear una representación JSON de algunos modelos de Rails usando Active Model Serializer, donde algunos modelos incorporan otros.Por ejemplo, tengo Evento y Asistentes, Evento tiene_y_pertenece_a_muchos asistentes.

class EventSerializer < ActiveModel::Serializer
  attributes :name

  has_many :attendees, serializer: AttendeeSerializer
end

class AttendeeSerializer < ActiveModel::Serializer
  attributes :name
end

Esto daría como resultado JSON como { name: 'Event One', attendees: [{ name: 'Alice' }, { name: 'Bob' }] }.

Ahora me gustaría agregar lo que los asistentes han dicho sobre el evento.Digamos que el comentario pertenece_al evento, pertenece_al asistente.Me gustaría incluir dichos comentarios en la salida serializada del evento, para que se convierta en { name: 'Event One', attendees: [{ name: 'Alice', comments: [{ text: 'Event One was great!'}] }, { name: 'Bob', comments: [] }] }.

podría tener

class AttendeeSerializer < ActiveModel::Serializer
  attributes :name

  has_many :comments
end

pero eso seleccionaría todos los comentarios de este asistente para todos los eventos, no es lo que quiero.Me gustaría escribir esto, pero ¿cómo encuentro el evento particular para el cual estoy realizando la serialización?¿Puedo acceder de alguna manera al objeto 'principal' o tal vez pasar opciones a un serializador 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

¿Es esto algo que se puede hacer o debería simplemente compilar el JSON de otra manera para este caso de uso en particular?

¿Fue útil?

Solución

Haría las cosas manualmente para tener el control:

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top