如何使ActiveModelSerializers序列化:属性并尊重我的key_transform?

时间:2016-11-14 23:34:56

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

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

这是配置问题吗?我错误地期望默认的:attributes适配器尊重:key_transform的设置(这似乎不太可能,基于我在课堂上阅读代码,但我经常是错的)?在我的代码中克制?还有别的吗?

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

控制器(一个或多个):

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

1 个答案:

答案 0 :(得分:0)

FWIW,我最终以答案结束了。从以前尝试解决这个问题,我知道如果我有一个模型的单个实例返回,我可以得到正确的答案。 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返回的数组的天真扩展失败了,因为键被留下了snake_case。

事实证明,“正确”(如果不满意)答案是:

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