Active Model Serializers 是一个属于关系。

28

本问题与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

当序列化一个UserCombination时,我想要嵌入整个主题子树。
当尝试使用此设置时出现以下错误:
undefined method `belongs_to' for UserCombinationSerializer:Class

我尝试将 UserCombinationSerializer 更改为:

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

在这种情况下,我没有收到任何错误,但是subject 序列化的方式不正确 - 没有使用 SubjectSerializer
我的问题: 1. 我不能在序列化器中使用 belongs_to 关系吗? 2. 如果不能 - 如何获得所需的行为 - 使用 SubjectSerializer 嵌入主题树?
3个回答

42

这并不是非常优雅,但它似乎可以正常工作:

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


4
好的,没问题。我觉得我现在更好地理解了has_one方法。在序列化器中,唯一有趣的是一个方法返回一个对象还是多个对象。因此,区分has_onebelongs_to并不重要。这种用词与ActiveRecord术语相符合是有点次优的,因为这些术语的意思并不相同。 - Jesper
我最近也遇到了同样的问题。是的,使用has_one :attribute对我有效。 - Kurt Mueller
11
ActiveModel::Serializer 的文档明确说明:“序列化器只关心多重性,而不关心所有权。您可以在序列化器中使用 has_one 来包含 belongs_to ActiveRecord 关联。” - awendt
@awendt,能否告诉我这在哪里明确说明了?我好像找不到。我并不是说你错了,我还是新手,对于查找文档的速度和效率,我在Rails/Ruby世界中还不够熟练。这也引出了一个真正的问题,如果不是显而易见的话,那就不是明确的。 - Andy
2
从我的经验来看,很遗憾没有一个中心位置可以找到文档。很多文档在Ruby文档上,很多在Github上,但是也有很多根本没有文档。大部分时间我都会在谷歌上花费很多时间。 - pjam
显示剩余2条评论

6
在 Active Model Serializer 0-10-stable 版本中,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

4
如果您尝试使用以下内容,会怎样呢:

如果您使用类似以下内容的东西:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接