活动模型序列化程序 - 自定义响应

时间:2016-05-26 19:20:01

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

我正在尝试为以下内容自定义序列化程序:

# in DB
{
  "id": 1,
  "measurement": 10.5,
  "sequence": 1,
  "time_stamp": "2016-05-25T04:53:38.000Z",
  "device_id": 2,
  "patient_id": 3,
  "measurement_type": "ecg"
},
{
  "id": 2,
  "measurement": 20.5,
  "sequence": 2,
  "time_stamp": "2016-05-25T04:53:38.000Z",
  "device_id": 2,
  "patient_id": 3,
  "measurement_type": "ecg"
}
{
  "id": 3,
  "measurement": 30.5,
  "sequence": 3,
  "time_stamp": "2016-05-25T04:53:38.000Z",
  "device_id": 2,
  "patient_id": 3,
  "measurement_type": "ecg"
}

# need to return this structure via GET
{
  "max_timestamp": "2020-05-25T04:53:38.000Z",
  "measurement_type": "ecg",
  "measurements": [
    { measurement: 10.5, sequence: 1, time_stamp: "2020-05-25T04:53:38.000Z" },
    { measurement: 20.5, sequence: 2, time_stamp: "2016-05-25T04:53:38.000Z" },
    { measurement: 30.5, sequence: 3, time_stamp: "2012-05-25T04:53:38.000Z" }
  ]
}

目前我有这个:

class PatchDataSerializer < ActiveModel::Serializer
  attributes :max_timestamp, :measurement_type, :measurements

  def measurements
    [{ :measurement => object.measurement, :sequence => object.sequence, :time_stamp => object.time_stamp.to_i }]
  end

  def max_timestamp
  end

end

返回:

[
  {
    "max_timestamp": null,
    "measurement_type": "ecg",
    "measurements": [
      {
        "measurement": 20.5,
        "sequence": 5,
        "time_stamp": 1464152018
      }
    ]
  },
  {
    "max_timestamp": null,
    "measurement_type": "ecg",
    "measurements": [
      {
        "measurement": 20.5,
        "sequence": 5,
        "time_stamp": 1464152018
      }
    ]
  }
]

正如您所看到的,这不起作用。我最大的问题是如何将每行measurements推入一个数组?我还需要为整个请求返回max_timestamp一次,而不是每一行。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

您可以为您尝试序列化的类创建自定义类方法,类似这样(我假设您按类型过滤?)

def self.measurements_of_type(type)
  {
    max_timestamp: Class.maximum(:time_stamp),
    measurement_type: type
    measurements: Class.where(type: type).select(:measurement, :sequence, :time_stamp)
  }
end

答案 1 :(得分:0)

在我看来,你可以创建一个新类来处理测量数据的聚合,然后为该类创建一个序列化器。

根据您使用的AMS版本,可以采用不同的方式完成,但要点几乎是

class MeasurementsAggregation
  attr_reader :measurements, :type, :max_timestamp

  def initialize(type, measurements)
    @measurements = measurements
    @max_timestamp = measurements.max_by(&:updated_at).updated_at
    @type = type
  end
end

那么你的序列化器就是

class MeasurementsAggregationSerializer < ActiveModel::Serializer
  attributes :max_timestamp, :type

  has_many :measurements, serializer: MeasurementSerializer
end

并且您的测量序列化器将是

class MeasurementSerializer < ActiveModel::Serializer
  attributes :measurement, :sequence, :time_stamp
end

您可能需要做一些调整才能让PORO与AMS合作,但这应该是它的主旨。