(Ruby on Rails active_model_serializers) How to move nested hash up one level in a 2-level deep association with ActiveModel::Serializer?

56 views Asked by At

I have the following ActiveRecord associations in Ruby on Rails:

class Driver
  has_one :car
  delegate :tires, to: :car
end
class Car
  belongs_to :driver
  has_many   :tires
end
class Tire
  belongs_to :car
end

I have the following Serializer:

class DriverSerializer < ActiveModel::Serializer
  attributes :id, :name

  has_one :car

  class CarSerializer < ActiveModel::Serializer
    attributes :id

    has_many :tires

    class TireSerializer < ActiveModel::Serializer
      attributes :id
    end
  end

end

The resulting JSON looks like this:

{
  "id": 1,
  "name": "Bob",
  "car": {
    "id": 1,
    "tires": [
      {
        "id": 1
      },
      {
        "id": 2
      }
      ...
    ]
  }
}

But I want the tires to move up one level so that they're nested directly under driver. I want to leverage the serializers as-is, without using Ruby's map method. I know I can do this:

class DriverSerializer < ActiveModel::Serializer
  attribute :tires

  def tires
    object.tires.map{|t| TireSerializer.new(t)}
  end
end

But is there a simpler way to just move the hash up one level?

1

There are 1 answers

0
Ali Ahmed On BEST ANSWER

I think it's better to use has_one :tires, through: :car association for the tires attribute in you Driver model instead of delegating it to :car. You can then use the has_many option in your DriverSerializer for this attribute and use TireSerializer for its serializer.

class Driver
  has_one :car
  has_many :tires, through: :car
end

and in your Driver serializer

class DriverSerializer < ActiveModel::Serializer
  has_many :tires, serializer: TireSerializer
end