在rails api活动模型序列化程序中为关联属性使用不同的键名

时间:2014-12-30 14:42:09

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

我正在使用Rest APIrails-api构建active-model-serializer,以便轻松过滤JSON中的必填字段。我也在这些序列化器中使用has_one关联。我想知道的是如何为has_one属性指定不同的密钥名称。

也就是说,我有两个模型说:EmployeeAddress,而has_one :address中有一个EmployeeSerializer。我得到的回应是:

{
  id: 1,
  address: {
   street: "some_street",
   city: "some_city"
  }
}

但我想得到以下回应:

{
  id: 1,
  stays: {
   street: "some_street",
   city: "some_city"
  }
}

我尝试使用has_one :address, :key => :stays,但这似乎不起作用。

3 个答案:

答案 0 :(得分:9)

您可以将stays定义为您希望在json中拥有的属性之一。

当然,序列化程序将转到模型实例,而不是在具有该名称的模型中找到属性。所以,它会坐在那里,为世界上:stays的价值而思考。

没关系,因为您可以在序列化程序中定义一个实例方法,告诉它该值应该是什么。在该实例方法中,您将获得object变量,该变量是序列化程序当前正在处理的对象。因此,object.address将是您的Address实例。

获得地址实例后,可以实例化一个序列化程序,该序列化程序将使用该实例显示其中列出的字段。我相信,root: false是必要的,否则:stays属性(或者在此情况下序列化程序为您提供的任何内容)将显示在另一个:stays属性中。

Employee的最终序列化程序应如下所示:

class EmployeeSerializer < ActiveModel::Serializer
  attributes :id, :name, :stays

  def stays
    MyAddressSerializer.new(object.address, root: false)
  end

end

答案 1 :(得分:6)

@janfoeh是对的。我刚刚在0.8版本中进行了测试,它运行得很好

    Gemfile中的
  1. gem "active_model_serializers", "~> 0.8.0"
  2. 杀死服务器
  3. $bundle install
  4. has_one :address, key: "stays"
  5. 启动服务器备份
  6. 效果很好!

    正如gem的文档所说的那样(here),&#34;你可能想要使用版本0.8&#34;

答案 2 :(得分:0)

  

自2016年4月起的0.10.0(感谢@AlfredoGallegos的评论)

发布的答案不适用于0.10.0 +

改为使用此:

ActiveModel::Serializer::CollectionSerializer.new
  (object.my_has_many_assoc, each_serializer: MySerializer)

而且似乎大多数人都转向Netflix JSONAPI gem,,它具有更多的支持,并且速度提高了25倍(但是please note it does not support是AMS的JSON默认设置)。

相关问题