I am working on a rails-api project where I am using active model serialiazer. But unfortunately its not working as expected. This is my V1::HuntsController
class V1::HuntsController < V1::MainController
def index
render json: Hunt.all
end
end
My hunts serializer looks like this
class HuntSerializer < ActiveModel::Serializer
belongs_to :user
attributes :id,:title,:picture_url,:clue
private
def picture_url
object.picture.url
end
end
But in my response i am getting all the attributes from hunt. I tried to explicitly define serializer to avoid versioning issues as well.
render json: {data: Hunt.all } ,each_serializer: HuntSerializer
But nothing seems to work. In the logs I can see,
[active_model_serializers] Rendered V1::HuntSerializer with Hash (32.36ms)
Whats happening here. Any help would be appreciated.
try
render json: Hunt.all, each_serializer: HuntSerializer (no need for data root)
then to verify that the serializer gets hit, put a byebug in the body of the picture_url function. if the byebug gets hit, you are indeed using your serializer. (must have gem byebug included in gemfile)
Related
I have the following api controller in ('app/controllers/api/v1/companies_controller.rb'):
class Api::V1::CompaniesController < ApplicationController
def index
companies = Company.all
render json: companies, serializer: CompanySerializer
end
end
but the above is looking for Api::V1::CompanySerializer in app/serializers/api/v1/company_serializer.rb. I'd rather just have a generic company serializer in app/serializers/company_serializer. I have tried using the scope resolution operator like:
render json: companies, serializer: ::CompanySerializer
but still getting an error. How would I tell my controller to use the default serializer explicitly? I have seen this issue https://github.com/rails-api/active_model_serializers/issues/1701 and, if this is the ONLY behavior allowed, it seems like a strange choice
AMS 0.10.7 Implicit Serializer vs Explicit Serializer
You really don't need to pass any serializer option as long as your serializer has the default name. So render json: companies should work.
Explicit way would look like:
render json: companies,
serializer: CollectionSerializer,
each_serializer: CompanySerializer
Note: The default serializer for collections is CollectionSerializer. In your example, you tried to pass CompanySerializer to serializer.
I'm updating the gem active_model_serializers from version 0.9.5 to 0.10.1. For version 0.9.5 the code below worked.
Controller:
def create
...
render json: #dia, app_rights: app_rights(#dia)
end
Serializer:
class Api::V1::SerializerWithSessionMetadata < ActiveModel::Serializer
attributes :app_rights
def app_rights
serialization_options[:app_rights]
end
end
The method serialization_options has been deprecated in version 0.10.1.
Here it is suggested to use instance_options instead.
Here it is suggested to use options: "instance_options is only available in the master branch, not in the current RC. In the current RC, you have to use options instead".
There are also suggestions for #options and #instance_options.
I have tried replacing serialization_options with all the above options. However, in all cases, after updating the gem, the json produced does not include app_rights. What am I doing wrong?
Using instance_options, your serializer should look like this:
class Api::V1::SerializerWithSessionMetadata < ActiveModel::Serializer
attributes :app_rights
def app_rights
#instance_options[:app_rights]
end
end
To ensure that the correct serializer gets called, you can render a specific serializer like this (otherwise it will render whatever is defined for the class on #dia):
render json: #dia, serializer: SerializerWithSessionMetadata, app_rights: app_rights(#dia)
Updated to Rails 4.2 and now I cannot for the life of me get the ActiveModel::Serializer configuration to work correctly.
ActiveModel::Serializer.setup do |config|
config.embed = :ids
config.embed_in_root = true
end
Previously, this worked great with:
respond_with #thing
With 4.2 (and 0.9.2 AMS), you have to say:
respond_with #thing, root: true
explicitly. Anyone understand why the global embed_in_root config no longer works?
I had the same trouble...
It appears that active model serializers 0.9.2 is not compatible with Rails 4.2.
What I think may be happening in your case is when you call:
respond_with #thing, root: true
you are not using the Active Model Serializers gem at all. I tested this by adding a custom attribute in my active model serializer, like this:
class ThingSerializer < ActiveModel::Serializer
attributes :this_is_a_test
def this_is_a_test
"and it does not work"
end
end
The this_is_a_test attribute was not turning up in my JSON so I realized that the active model serializer was not in use.
I followed igagnidz and added this to my application controller:
def _render_with_renderer_json(json, options)
serializer = build_json_serializer(json, options)
if serializer
super(serializer, options)
else
super(json, options)
end
end
This is what finally got me through it: https://github.com/rails-api/active_model_serializers/issues/641
I have a simple Rails 3.2 controller which is consumed as an API with JSON:
module Api
module V1
class ReportsController < Api::V1::ApplicationController
def index
respond_with Report.where(name: params[:name])
end
end
end
end
(there is no code is the parent controllers)
When I consume this method, I'm getting all reports back, as expected, but I'm also getting all the associations. I don't see why this is and want to stop it.
Why am I getting the associations?
As #rmagnum2002 eluded to, I found active_model_serializers bundled into the app, and someone had created a serializer for that model without me noticing it.
In my application I have a model that is below;
class Init < ActiveRecord::Base
attr_accessor :clientAvailability
attr_accessible :returnCode, :returnMessage, :tokenCode, :updateURL
end
In here when I've added the **attr_accessor** later on and when I try to apply **render json: init** it doesn't show the **clientAvailability** property even though I've set it as;
init=Init.new
init.clientAvailability="3"
When I debug it I can see that it is set, but doesn't simply show up when I try to render it as json. What could be the thing I'm missing?
Is clientAvailability a column in the DB? If not, then I suppose it is the default way - to serialize only the DB attributes. But you can do:
render json: init, methods: [:clientAvailability]
to include clientAvailability attribute.