Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting Rails 5 app to return JSON API format

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!

like image 718
Zack Shapiro Avatar asked Jun 16 '17 21:06

Zack Shapiro


1 Answers

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.

like image 140
George Avatar answered Sep 18 '22 07:09

George