数组中不同类的active_model_serializers

时间:2013-10-11 15:52:17

标签: ruby-on-rails ruby active-model-serializers

FeedController返回一个包含这些类对象的数组:Product,Kit和Article。

是否有可能以及如何使用active_model_serializers为产品应用ProductSerializer,为Kit应用KitSerializer和为文章应用ArticleSerializer?

这应该是这样的:

[
  { "type": "product", other fiels of Product },
  { "type": "kit", other fiels of Kit },
  { "type": "article", other fiels of Article }
]

2 个答案:

答案 0 :(得分:2)

这应该与version 0.9.0一起使用,version 0.10.0应该在最终准备就绪时支持这种情况,但在此答案时,建议您不要使用该版本(主/边缘)

class MyArraySerializer < ActiveModel::ArraySerializer

  def initialize(object, options={})
    options[:each_serializer] = get_serializer_for(object)
    super(object, options)
  end

  private
  def get_serializer_for(klass)
    serializer_class_name = "#{klass.name}Serializer"
    serializer_class = serializer_class_name.safe_constantize

    if serializer_class
      serializer_class
    elsif klass.superclass
      get_serializer_for(klass.superclass)
    end
  end
end

您可以修改get_serializer_for方法以更好地满足您的需求。我用它来处理STI子类,其中我的父类定义了所有属性。但是,您需要为每个单独的对象配置单独的序列化器,因为属性很可能会有所不同。

然后在你的控制器中:

render json: @my_array_of_mixed_classes, serializer: MyArraySerializer

答案 1 :(得分:0)

如果使用开箱即用的active_model_serializers是不可能的,那么原因可能是您的API响应设计有些非标准。例如如果我不得不使用你的API,我会很容易反序列化你的JSON响应吗?

解决此问题的一种方法是重新设计API响应:

...
"products" : [ ARRAY of Product ],
"kits" : [ ARRAY of Kit ],
"articles" : [ ARRAY of Article ]
....

API用户也可以更容易地反序列化。