6

I'm trying to get my app to return in lowercase camelcase for eventual JSON API formatting.

I've installed gem 'active_model_serializers' and created a new initializer with the following code in it:

ActiveModelSerializers.config.adapter = :json_api
ActiveModelSerializers.config.key_transform = :camel_lower

Then I have a small API that returns json, as all of the best internet applications do:

class Api::V1::UsersController < API::V1::BaseController
  def sky
      @user = User.find_by_id(params[:user_id])

      if @user
          obj =  {
              sky: {
                  sectors: @user.sectors,
                  slots: @user.slots
              }
          }

          render json: obj
      else
          raise "Unable to get Sky"
      end
  end

More on the API controller inheritance pattern: class API::V1::BaseController < ActionController::Base

The Problem

In my API response, things are still snake cased and I see this error in the console [active_model_serializers] Rendered ActiveModel::Serializer::Null but my research has led me to a dead end as to what to do.

Any suggestions would be very welcome. Thanks!

1
  • This is a rails app, not a rails-api app, fwiw Commented Jun 16, 2017 at 21:42

4 Answers 4

3

The problem is you're not calling an active record serializer in your controller, so those config settings aren't being picked up.

Solution: Create a UserSerializer in "app/serializers/user_serializer.rb" that should look something like this:

class UserSerializer < ActiveModel::Serializer
  attributes :id

  has_many :sectors
  has_many :slots
end

as well as similarly structured SectorSerializer and a SlotSerializer with all of the attributes you want from each (Here are the getting started docs and the general syntax docs for active record serializers)

Then in your controller:

class Api::V1::UsersController < API::V1::BaseController
  def sky
    @user = User.includes(:sectors, :slots).find_by_id(params[:user_id])

    if @user
      render json: @user
    else
      raise "Unable to get Sky"
    end
  end
end

Which will eager load :slots and :sectors with includes then calls your UserSerializer using your camel_case config options.

Sign up to request clarification or add additional context in comments.

14 Comments

No. It's still camel cased
snake cased, rather
@zack which version of active model serializers are you using?
run bundle show | grep active_model_serializers to get the version
active_model_serializers (0.10.6)
|
3
+25

In your controller put respond_to :json

class Api::V1::UsersController < API::V1::BaseController

  respond_to :json

and in the action put same that you have

def sky
   ...      
   render json: obj
   ...       
end

and define in base controller

protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == 'application/json' }

1 Comment

Still snake cased
2

From this pull request (*) it looks like you should be able to configure key_format = :lower_camel in your ActiveModel::Serializers config.

(*) https://github.com/rails-api/active_model_serializers/pull/534

Comments

2

i think it helps you. in my case i use gem 'active_model_serializers', '~> 0.10.5' which depends on case_transform (>= 0.2)

and in rails console i can do

CaseTransform.camel_lower(initially_serialized_output)                                                       
=> {:name=>"My Company", :jsonThings=>{:rating=>8, :aKey=>{:aSubkey=>{:anotherKey=>"value"}}}}

my research was by steps: https://github.com/rails-api/active_model_serializers/pull/1993 => https://github.com/NullVoxPopuli/case_transform-rust-extensions

did you find this?

1 Comment

initially_serialized_output = { "name": "My Company", "json_things": { "rating": 8, "a_key": { "a_subkey": { "another_key": "value" } } } }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.