2016-11-14 2 views
1

У меня очень простая модель, которую я хочу сериализовать в 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.Как заставить ActiveModelSerializers сериализоваться с помощью: атрибутов и уважения к key_transform?

Это проблема конфигурации? Я неправильно ожидаю, что адаптер по умолчанию :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 

ответ

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 
Смежные вопросы