ruby-on-rails - new - rails api json serializer
Rails Active Model Serializer: tiene muchos y accede al registro principal (1)
Estoy tratando de construir una representación JSON de algunos modelos de Rails utilizando Active Model Serializer, donde algunos modelos incorporan otros. Por ejemplo, tengo Evento y Asistentes, Evento has_and_belongs_to_many Asistentes.
class EventSerializer < ActiveModel::Serializer
attributes :name
has_many :attendees, serializer: AttendeeSerializer
end
class AttendeeSerializer < ActiveModel::Serializer
attributes :name
end
Esto daría lugar a 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, el comentario pertenece a un evento, pertenece a un 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 lo que quiero. Me gustaría escribir esto, pero ¿cómo encuentro el evento en particular para el que estoy realizando la serialización? ¿Puedo acceder de alguna manera al objeto ''padre'', 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 debo simplemente construir el JSON de otra manera para este caso de uso en particular?
Haría las cosas manualmente para obtener 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