Active_model_serializers: belongs_to and has_one Nested Form Use Wrong Serializer

Created on 22 Sep 2015  路  22Comments  路  Source: rails-api/active_model_serializers

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?

Needs Bug Verification Needs Submitter Response

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 your render call so that _all_ associations will be serialized recursively.

All 22 comments

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?

@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.

screenshot 2015-10-18 23 14 27

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

axsuul picture axsuul  路  4Comments

greggawatt picture greggawatt  路  4Comments

seoyoochan picture seoyoochan  路  4Comments

PratheepV picture PratheepV  路  4Comments

iggant picture iggant  路  4Comments