Hi, I have a problem with nested serializer. This is my serializers
class FormulaSerializer < ActiveModel::Serializer
belongs_to :author
has_many :steps
has_many :cook_ingredients
has_many :stock_locations
end
class CookIngredientSerializer < ActiveModel::Serializer
has_one :ingredient, each_serializer: IngredientSerializer
has_one :unit
attributes :description, :quantity, :ingredient, :unit
end
class IngredientSerializer < ActiveModel::Serializer
attributes :id, :name
has_many :products
end
My formulas API result.
Actual result:
{
"formulas":
[{
"steps": , // some data
"cook_ingredients": [
{
"ingredient": {
"id": 3,
"name": "bawang",
"created_at": "2015-08-05T06:27:20.065Z",
"updated_at": "2015-08-26T06:53:16.874Z",
"taxon_id": null
}
}
],
"stock_locations": [
{
"id": 2,
}]
}]
}
Why there is created_at, updated_at, and taxon_id is there? It seem that it rendered without using my serializer.
Expected result
{
"formulas":
[{
"steps": , // some data
"cook_ingredients": [
{
"ingredient": {
"id": 3,
"name": "bawang",
"products": [] // some products
}
}
],
"stock_locations": [
{
"id": 2,
}]
}]
}
The serializers works perfectly if I render the Ingredient API. Is this a bug?
This behavior happens when AMS cannot find a suitable serializer. It then falls back to transforming the raw object to JSON. Here, has_one :ingredient, each_serializer: IngredientProductSerializer should be has_one :ingredient, serializer: IngredientProductSerializer (without the each).
And given the example code, IngredientProductSerializer should be IngredientSerializer
I'm sorry. It was a typo. I changed it into IngredientSerializer and it keeps outputting the same result
@edwinlunando Do you made the changes that @beauby said?
@edwinlunando See https://github.com/rails-api/active_model_serializers/issues/1189#issuecomment-142241016
@dukex @beauby Update on this. I already tried
class CookIngredientSerializer < ActiveModel::Serializer
has_one :ingredient, serializer: IngredientSerializer
has_one :unit
attributes :description, :quantity, :ingredient, :unit
end
and
class CookIngredientSerializer < ActiveModel::Serializer
has_one :ingredient
has_one :unit
attributes :description, :quantity, :ingredient, :unit
end
Still not as expected result.
The problem is on finding serializers is that the IngredientSerializer works perfectly if I use the ingredients API.
I think your problem is that you have both an attribute and an association named ingredient. Your associations should not be in the list of attributes.
Ok, I tried removing them from the attributes
class CookIngredientSerializer < ActiveModel::Serializer
has_one :ingredient
has_one :unit
attributes :description, :quantity
end
The ingredient and unit key is not on the result set.
Any idea?
Trying with single attribute is the same. It uses the wrong serializer.
class CookIngredientSerializer < ActiveModel::Serializer
# belongs_to :ingredient
belongs_to :unit
attributes :description, :quantity
attribute :ingredient, serializer: IngredientSerializer
end
If it is an association, it should not be defined as an attribute. Could you post your render call (in your controller) as well?
@edwinlunando The following should work:
class CookIngredientSerializer < ActiveModel::Serializer
belongs_to :ingredient, serializer: IngredientSerializer
belongs_to :unit
attributes :description, :quantity
end
I'm closing this for now, as it is a usage issue and not an AMS issue. Feel free to keep commenting if you need further assistance (or better yet, open a StackOverflow question and link it here).
@edwardloveall does it works for you? Can you give us some update on it?
@joaomdmoura Did you mean @edwinlunando?
@edwardloveall I'm sure he did ;) Thanks for pinging @edwinlunando
Here is the update. Both the ingredient and unit key is not printed out.

By design, only the first level associations are serialized (this is being discussed currently). In your case, you could add include: '**' in your render call so that _all_ associations will be serialized recursively.
AHHHH, I see. It works purrfectly now. I think we need to add this to the readme. :smile:
Wait. After I tried it again, it did not work and when I check the guide, include: '**' is only working for :json_api while I am using :json. any idea?
You can use `include: '**'藡 with the Json adapter in master.
I'm adding gem 'active_model_serializers', github: 'rails-api/active_model_serializers'
And it give me errors like a ruby interpreter bug. This is part of the stack trace.
7f08a9147000-7f08a914c000 rw-p 00000000 00:00 0 [stack:7]
7f08a914c000-7f08a9152000 rw-p 002c0000 00:26 28 /usr/local/bin/ruby
7f08a9152000-7f08a9177000 rw-p 00000000 00:00 0
7f08aa273000-7f08b1f7e000 rw-p 00000000 00:00 0 [heap]
7ffd65c91000-7ffd65cb2000 rw-p 00000000 00:00 0 [stack]
7ffd65db9000-7ffd65dbb000 r--p 00000000 00:00 0 [vvar]
7ffd65dbb000-7ffd65dbd000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html
How about it?
Is there any release data for the next version release? I think I need this feature, but I cannot use the master.
Most helpful comment
By design, only the first level associations are serialized (this is being discussed currently). In your case, you could add
include: '**'in yourrendercall so that _all_ associations will be serialized recursively.