如何使 ActiveModelSerializers 使用 :attributes 序列化并尊重我的 key_transform?

How do I cause ActiveModelSerializers to serialize with :attributes and respect my key_transform?

我有一个非常简单的模型,我希望在 Rails (5) API 中序列化。我想将生成的 JSON 键生成为 CamelCase(因为这是我的客户所期望的)。因为我预计该模型将来会增加复杂性,所以我认为我应该使用 ActiveModelSerializers。因为 API 的使用者需要一个普通的 JSON 对象,所以我想使用 :attributes 适配器。但是,无论我是在配置文件中设置 ActiveModelSerializers.config.key_transform = :camel 还是通过 s = ActiveModelSerializers::SerializableResource.new(t, {key_transform: :camel}) 创建资源(其中 t 表示控制器中要序列化的 ActiveModel 对象)。无论哪种情况,我都调用 render json: s.as_json.

这是配置问题吗?我是否错误地期望默认 :attributes 适配器遵守 :key_transform 的设置(根据我对 class 中代码的阅读,这似乎不太可能,但我经常错了)?我的代码有问题吗?还有别的吗?

如果其他信息有帮助,请询问,我会编辑我的问题。

控制器:

class ApplicationController < ActionController::API

  before_action :force_json

  private

  def force_json
    request.format = :json
  end
end

require 'active_support'
require 'active_support/core_ext/hash/keys'
class AvailableTrucksController < ApplicationController

  def show
    t = AvailableTruck.find_by(truck_reference_id: params[:id])
    s = ActiveModelSerializers::SerializableResource.new(t, {key_transform: :camel})
    render json: s.as_json
  end
end

config/application.rb

require_relative 'boot'
require 'rails/all'

Bundler.require(*Rails.groups)

module AvailableTrucks
  class Application < Rails::Application
    config.api_only = true
    ActiveModelSerializers.config.key_transform = :camel
    # ActiveModelSerializers.config.adapter = :json_api
    # ActiveModelSerializers.config.jsonapi_include_toplevel_object = false
  end
end


class AvailableTruckSerializer < ActiveModel::Serializer
  attributes :truck_reference_id, :dot_number, :trailer_type, :trailer_length, :destination_states,
             :empty_date_time, :notes, :destination_anywhere, :destination_zones

end

FWIW,我最终得到了一个答案。从以前解决这个问题的尝试中,我知道如果我有一个模型实例到 return,我就能得到正确的答案。 ActiveModel::Serialization 的工作旨在解决如何使用控制器的 #index#get 方法实现该结果。

因为我有这个以前的结果,我改为扩展它来解决我的问题。以前,我知道如果我这样做会生成正确的响应:

  def show
    t = AvailableTruck.find_by(truck_reference_id: params[:id])
    render json: t.as_json.deep_transform_keys(&:camelize) unless t.nil?
  end

让我感到沮丧的是,AvailableTruck.all 对 return 数组的天真扩展失败了,因为键留下了 snake_case。

结果 "correct"(如果不满意)答案是:

  def index
    trucks = []
    AvailableTruck.all.inject(trucks) do |a,t|
      a << t.as_json.deep_transform_keys(&:camelize)
    end
    render json: trucks
  end