Using a different key name for an association attribute in rails api active model serializer

swaroopsm picture swaroopsm · Dec 30, 2014 · Viewed 8.1k times · Source

I am building a Rest API using rails-api and active-model-serializer to easily filter the required fields in the JSON. I am also using the has_one association in these serializers. All I wanted to know is how do I specify a different key name for the has_one attribute.

That is, I have two models say: Employee and Address, and there is a has_one :address in say EmployeeSerializer. The response that I get is:

{
  id: 1,
  address: {
   street: "some_street",
   city: "some_city"
  }
}

But I would like to get the following response:

{
  id: 1,
  stays: {
   street: "some_street",
   city: "some_city"
  }
}

I tried using has_one :address, :key => :stays, but that doesn't seem to work.

Answer

Kalman picture Kalman · Dec 30, 2014

You can define stays as one of the attributes you want to have in your json.

Naturally, the serializer will go to the model instance and not find an attribute in the model with that name. So, it will be sitting there scratching its head as to what in the world the value of :stays should be.

That's OK, because you can define an instance method in your serializer telling it exactly what that value should be. In that instance method, you are given object variable which is the object the serializer is currently processing. object.address therefore will be your Address instance.

Once you have your address instance, you can instantiate a serializer which will use that instance to display the fields outlined inside of it. I believe, root: false is necessary as otherwise, :stays attribute (or whatever the serializer gives you back in this case) will be displayed inside another :stays attribute.

Your final serializer for Employee should look as follows:

class EmployeeSerializer < ActiveModel::Serializer
  attributes :id, :name, :stays

  def stays
    MyAddressSerializer.new(object.address, root: false)
  end

end