如何使 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
我有一个非常简单的模型,我希望在 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