Ethan
Ethan

Reputation: 9768

Active Model Serializers - Is it possible to show the URL for an embedded object?

I'm trying to make my API highly connected/crawlable, so I want all embedded object associations to return the URL to the associated object, as well as the ID and attributes of the associated object.

For example given:

class Car < ActiveModel::Serializer
  attributes :id, :make, :model, :url
  has_many :passengers

  def url
    car_url(object)
  end
end

class Passenger < ActiveModel::Serializer
  attributes :id, :name, :url

  def url
    passenger_url(object)
  end
end

I want http://api.approot.com/car/3.json to return something like:

{        
  - car: {
      id: 3,
      make: 'Ford',
      model: 'F150',
      url: 'http://api.approot.com/car/3.json',
    - passengers: [
        - {
             id: 7,
             name: 'Bill',
             url: 'http://api.approot.com/passengers/7'
           },
        - {
             id: 13,
             name: 'Will',
             url: 'http://api.approot.com/passengers/13'
          }
      ]
    }
}

Given this implementation however, ActiveModel::Serializers will currently not display the 'url' attribute for Passenger when you visit Car (since 'object' is, I suspect, not defined for Passenger in the scope of viewing the Car object accessed through the above example URL).

Any ideas on how to work around this?

Thanks!

Upvotes: 3

Views: 3822

Answers (2)

Bernard Lomo
Bernard Lomo

Reputation: 11

This is a DIY way to solve this problem. Create a field on the model to store the url. then after the object has been saved, you update it with a manually generated url like this. here is how i solved it.

if @questionsolution.save
generatedurl = 'http://localhost:3000/questionsolutions/' + @questionsolution.id.to_s
@questionsolution.update(solutionurl: generatedurl)
end

then you can get the url from the resource direclty without depending on active model serializers to do it for you.

Upvotes: 0

James Mason
James Mason

Reputation: 4296

Since you aren't in the context of a view/controller, you probably need to pass the :host option to your *_url methods.

def url
  car_url(object, host: "api.approot.com")
end

Upvotes: 1

Related Questions