Rails Active Serializer модели - has_many и доступ к родительской записи
Я пытаюсь создать JSON-представление некоторых моделей Rails с помощью Active Model Serializer, где некоторые модели встроят другие. Например, у меня есть событие и участники, событие 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
Это приведет к JSON как { name: 'Event One', attendees: [{ name: 'Alice' }, { name: 'Bob' }] }
.
Теперь я хотел бы добавить то, что участники рассказали о событии. Скажем, комментарий принадлежит_ событию, принадлежит_обходимому участнику. Я хотел бы включить указанные комментарии в сериализованный вывод события, поэтому он станет { name: 'Event One', attendees: [{ name: 'Alice', comments: [{ text: 'Event One was great!'}] }, { name: 'Bob', comments: [] }] }
.
Я мог бы
class AttendeeSerializer < ActiveModel::Serializer
attributes :name
has_many :comments
end
но это будет выбирать все комментарии этого участника для всех событий - не то, что я хочу. Я хотел бы написать это, но как мне найти конкретное событие, для которого я делаю сериализацию? Могу ли я каким-либо образом получить доступ к "родительскому" объекту или, возможно, передать параметры в сериализатор 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
Это что-то, что можно сделать, или я должен просто построить JSON по-другому для этого конкретного случая использования?
Ответы
Ответ 1
Я бы сделал все вручную, чтобы получить контроль:
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