Подтвердить что ты не робот

Активные модели Сериализаторы принадлежат_to

Этот вопрос относится к AMS 0.8

У меня две модели:

class Subject < ActiveRecord::Base
  has_many :user_combinations
  has_ancestry
end

class UserCombination < ActiveRecord::Base
  belongs_to :stage
  belongs_to :subject
  belongs_to :user
end

И два сериализатора:

class UserCombinationSerializer < ActiveModel::Serializer
      attributes :id
      belongs_to :stage
      belongs_to :subject
end

class SubjectSerializer < ActiveModel::Serializer
  attributes :id, :name, :description, :subjects

  def include_subjects?
    object.is_root?
  end

  def subjects
    object.subtree
  end
end

Когда a UserCombination сериализуется, я хочу встроить все поддерево объектов.

Когда я пытаюсь использовать эту настройку, я получаю эту ошибку:

undefined method `belongs_to' for UserCombinationSerializer:Class

Я попытался изменить UserCombinationSerializer на это:

class UserCombinationSerializer < ActiveModel::Serializer
  attributes :id, :subject, :stage
end

В этом случае я не получаю ошибок, но subject сериализуется неправильно, не используя SubjectSerializer.

Мои вопросы:

  • Должен ли я использовать отношение belongs_to в сериализаторе?
  • Если нет - как я могу получить желаемое поведение - встраивание дерева объектов с помощью SubjectSerializer?
4b9b3361

Ответ 1

Это не очень элегантно, но кажется, что он работает:

class UserCombinationSerializer < ActiveModel::Serializer
  attributes :id, :stage_id, :subject_id

  has_one :subject
end

Мне не очень нравится называть has_one, тогда как на самом деле ассоциация belongs_to:/

РЕДАКТИРОВАТЬ: проигнорируйте мой комментарий о has_one/belongs_to неоднозначности, документ действительно довольно ясно об этом: http://www.rubydoc.info/github/rails-api/active_model_serializers/frames

Ответ 2

Что делать, если вы попытаетесь сделать что-то вроде этого:

class UserCombinationSerializer < ActiveModel::Serializer
  attributes :subject,
             :stage,
             :id

  def subject
    SubjectSerializer.new(object.subject, { root: false } )
  end

  def stage
    StageSerializer.new(object.stage, { root: false } )
  end
end

Ответ 3

В Active Serializer модели 0-10-стабильный, belongs_to теперь доступен.

belongs_to :author, serializer: AuthorPreviewSerializer
belongs_to :author, key: :writer
belongs_to :post
belongs_to :blog
def blog
  Blog.new(id: 999, name: 'Custom blog')
end

https://github.com/rails-api/active_model_serializers/blob/0-10-stable/docs/general/serializers.md#belongs_to

Итак, вы можете сделать:

class UserCombinationSerializer < ActiveModel::Serializer
  attributes :id
  belongs_to :stage, serializer: StageSerializer
  belongs_to :subject, serializer: SubjectSerializer
end