Rails Active Model Serializer - has_many и доступ к родительской записи

StackOverflow https://stackoverflow.com//questions/25010544

Вопрос

Я пытаюсь создать JSON-представление некоторых моделей Rails, используя Active Model Serializer, где некоторые модели встраивают другие.Например, у меня есть событие и участники, событие имеет_and_belongs_to_many участников.

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' }] }.

Теперь я хотел бы добавить то, что сказали участники об этом мероприятии.Допустим, комментарий принадлежит событию, принадлежит участнику.Я бы хотел включить указанные комментарии в сериализованный вывод event, чтобы он стал { 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 другим способом для данного конкретного случая использования?

Это было полезно?

Решение

Я бы делал все вручную, чтобы получить контроль:

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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top