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)
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 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)
I use active_model_serializers (0.9.2). I've been studying documention, stack and source code and still cant find some way to pass some parameter to serializer. The only one workaround is using default scope
def default_serializer_options
{
scope: some_param
}
end
#options, options orserialization_options seems to be not working for me.
This is the link which will help you with it link
First create a serializer in the serializer folder.
class AttachmentSerializer < ActiveModel::Serializer
attributes :id, :attachment_url
def attachment_url
object.attachment_url
end
end
Then in your controller you can do something like this
params.require(:model-name).permit( :attachment)
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
Using Rails 3.2, I'm working on an API backed model (not ActiveRecord). I want to be able to call to_json on this model in Rails controllers. After reading through a bunch of the ActiveModel docs I'm still not clear on one thing:
Given a model like this:
class MyModel
attr_accessor :id, :name
def initialize(data)
#id = data[:id]
#name = data[:name]
end
def as_json
{id: #id, name: #name}
end
end
Should this work as expected, or do I also need to include ActiveModel::Serializers::JSON? I'm having a hard time figuring out where the as_json / to_json methods are normally defined and when Rails calls which ones automatically in different circumstances...
Thanks for any insight!
Yes this does work, however not quote as you've written in.
When you render json in a controller using
def action
render :json => #my_model
end
Then Rails will automatically call to_json on your object and as long as you've defined to_json this will work as expected.
If your controller uses the Rails 3 content negotiation shenanigans, ie.
class Controller < ApplicationController
respond_to :json, :html
def action
respond_with(#my_model)
end
Then you will need to override as_json on your class, but the method signature requires an optional hash of options to be compatible with ActiveSupport so in this case you want
def as_json(options={})
...
end
Alternatively If you include ActiveModel::Serializers::JSON into your Class and your class supports the attributes method that returns a hash of attrs and their values - then you'll get as_json for free - but without the control of the resultant structure that you have if you just override the method by hand.
Hope this helps.